2

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?

gputhige
  • 109
  • 2
  • 11
  • 3
    _dbHelper is not initialized i think – UTKARSH Sharma Oct 23 '20 at 14:29
  • 2
    Thanks @UTKARSHSharma - That solves the issue. The _dbHelper was not initiated. – gputhige Oct 23 '20 at 16:41
  • please upvote my answer that will help me if you find it correct. @gputhige – UTKARSH Sharma Oct 23 '20 at 18:28
  • 1
    FWIW, the docs (https://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. – Amos Joshua Mar 21 '22 at 19:40

1 Answers1

2

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

return Container(
              child: Text('Printing ${snapshot.data}'),
            );
Ravi Singh Lodhi
  • 2,605
  • 1
  • 9
  • 12