Futurebuilder in StatelessWidget - Flutter

3,443

Instead of printing _count, you need to use snapshot.data to get the value returned from _getCat.

return Container(
              child: Text('Printing ${snapshot.data}'),
            );
Share:
3,443
gputhige
Author by

gputhige

Updated on December 25, 2022

Comments

  • gputhige
    gputhige over 1 year

    I have the following code in a Stateful Widget and the future: in Futurebuilder correctly calls the function _getCategory()

    class Categories extends StatefulWidget {
      @override
      _CategoriesState createState() => _CategoriesState();
    }
    
    class _CategoriesState extends State<Categories> {
      List<AllAccounts> _allaccounts;
      DatabaseHelper _dbHelper;
      int _count = 0;
    
      @override
      void initState() {
        super.initState();
        setState(() {
          _dbHelper = DatabaseHelper.instance;
        });
        _getCategory();
      }
    
      Future _getCategory() async {
        List<AllAccounts> x = await _dbHelper.getCategory();
        setState(() {
          _allaccounts = x;
        });
        _count = _allaccounts.length;
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text('Add/Edit Categories'),
          ),
          body: Center(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.start,
              children: [
                SizedBox(
                  height: 20.0,
                ),
                Text('Select a Category', style: TextStyle(fontSize: 18.0),),
                SizedBox(
                  height: 20.0,
                ),
                _list(),
              ],
            ),
          ),
        );
      }
    
      _list() =>
          Expanded(
            child: ListView.builder(
              itemCount: _count,
              itemBuilder: (context, position) {
                return Card(
                  color: Colors.grey[600],
                  elevation: 2.0,
                  child: ListTile(
                    leading: Icon(Icons.group),
                    title: Text(_allaccounts[position].category,
                      style: TextStyle(fontSize: 17.0),),
                    trailing: Icon(Icons.arrow_forward),
                    onTap: (){},
                  ),
                );
              },
            ),
          );
    
    }
    

    However, when I try the same thing in a StatelessWidget, the future: in Futurebuilder is not called.

    class Test extends StatelessWidget {
      List<AllAccounts> _allaccounts;
      DatabaseHelper _dbHelper;
      int _count = 0;
    
    
      Future<int> _getCat() async {
        List<AllAccounts> x = await _dbHelper.getCategory();
        _allaccounts = x;
        _count = x.length;
        print(_count);
        return _count;
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text('Test'),
          ),
          body: Center(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.start,
              children: [
                _list(),
              ],
            ),
          ),);
      }
    
      _list() => Expanded(
            child: FutureBuilder<int>(
              builder: (context, snapshot) {
                if (snapshot.connectionState == ConnectionState.none &&
                    snapshot.hasData == null) {
                  return Center(
                    child: CircularProgressIndicator(),
                  );
                }
                return Container(
                  child: Text('Printing $_count'),
                );
              },
              future: _getCat(),
            ),
          );
    }
    

    Text('Printing $_count) returns 'Printing 0'. Also the print in the _getCat() function does not show-up in the console.

    Is there a problem in the way Futurebuilder is used in the Stateless Widget?

    • UTKARSH Sharma
      UTKARSH Sharma over 3 years
      _dbHelper is not initialized i think
    • gputhige
      gputhige over 3 years
      Thanks @UTKARSHSharma - That solves the issue. The _dbHelper was not initiated.
    • UTKARSH Sharma
      UTKARSH Sharma over 3 years
      please upvote my answer that will help me if you find it correct. @gputhige
    • Amos Joshua
      Amos Joshua about 2 years
      FWIW, the docs (api.flutter.dev/flutter/widgets/FutureBuilder-class.html) explicitly say not to create the future from within the build method of a stateless widget. It seems that this causes the future to get created again on every build, which can return different data - effectively adding "state" into your stateless widget.