camstar915
camstar915

Reputation: 153

How do I prevent Flutter FutureBuilder from firing early?

I'm using the following FutureBuilder to handle fetching 'squad' info from a Firebase database, but the Future is saying it's done before I can process all the data form the database:

@override
  Widget build(BuildContext context) {
    return FutureBuilder(
      future: _getUserSquads(),
      builder: (ctx, snapshot) {
        if (snapshot.connectionState == ConnectionState.waiting) {
          return Center(
            child: CircularProgressIndicator(),
          );
        } else {
          if (_userSquads == null) {...} else {
            print(snapshot.connectionState);
            return Text(_userSquads.length.toString());
          }
        }
      },
    );

... the following two functions are the functions I need to be completed before the FutureBuilder is done:

Future<void> _getUserSquads() async {
    print('1');
    final squadIdsResult = await _userSquadsRef.once();
    print('2');
    if (squadIdsResult.value == null) {
      print('3');
      return;
    }
    print('4');
    _userSquadIds = squadIdsResult.value;
    print('5');
    final test = await _test();
    print('6');
}
  Future<void> _test() {
    print('7');
    _userSquadIds.forEach((key, value) async {
      print('itter');
      final result = await _squadsRef.child(key).once();
        _userSquads.add(result.value);
        print(result.value);
        print(_userSquads);
      });
      print('8');
    print('9');
  }

The two print statements print(result.value) and print(_useraSquads) don't execute until after the Future's connection state is done:

I/flutter (29217): 2
I/flutter (29217): 4
I/flutter (29217): 5
I/flutter (29217): 7
I/flutter (29217): itter
I/flutter (29217): 8
I/flutter (29217): 9
I/flutter (29217): 6
I/flutter (29217): ConnectionState.done
I/flutter (29217): {squadName: SAFTS}
I/flutter (29217): [{squadName: SAFTS}]

It seems like the problem is in the _test() function, but I've tried a hundred different ways to write this, and I can't figure out how to make sure that the code is done fetching the data from the database in the forEach block before the Future is set to done.

Upvotes: 0

Views: 465

Answers (1)

Viren V Varasadiya
Viren V Varasadiya

Reputation: 27147

Your _userSquadIds's foreach is creating issue. If you want to make it async the you can use Future.forEach.

Change following code.

_userSquadIds.forEach((key, value) async {
      print('itter');
      final result = await _squadsRef.child(key).once();
        _userSquads.add(result.value);
        print(result.value);
        print(_userSquads);
      });

With Following one.

 await Future.forEach(_userSquadIds, (key,value) async {
     print('itter');
      final result = await _squadsRef.child(key).once();
        _userSquads.add(result.value);
        print(result.value);
        print(_userSquads);
    });

Upvotes: 1

Related Questions