majourtip
majourtip

Reputation: 3

How to define a Future list the right way?

I am kinda new to flutter and dart and I am trying to use the future builder to create some widget which get data from firebase. What is actually not working for me is my future function because I basically do not return a future. This is my function which I want to use. Here friends is a list of users which is taken to access the data on firebase. My Problem lays in the definition of the List trial which is returned empty whithout any future in it. The code where I get the data for each member seems to work just fine at least the data is added and then the widget builds itself up but before that I have this empty list returned which returns a true on snapshots.hasData. Would be awesome if someone could help me out here. Actually in my opinion I have a List of futures but I do not quite understand how to get this into there.

    `Future<List<dynamic>> _getData(members) async {
      List trial = [];
      int _daysUntilBirthday;
     friends.map((friend) async => await DatabaseService().getUserInfo(
            generalServices().destructureId(friend),
            ['uid']).then((snapshots) {
          trial.add({
            'uid': snapshots[0],
           });
        }))
    //.toList()
    ;
return trial;`

My futureBuilder is created within a streamBuilder:

 Widget build(BuildContext context) {
return StreamBuilder(
  stream: _members,
  builder: (context, snapshot) {
    if (snapshot.hasData) {
      if (snapshot.data['members'] != null) {
        if (snapshot.data['members'].length != 0) {
          AsyncSnapshot<dynamic> _userData = snapshot;

          return FutureBuilder<List>(
              future: _getData(_userData.data['members']),
              builder: (context, AsyncSnapshot<List> snapshot) {
                
                if (snapshot.hasData) {
                  if (snapshot.data != null) {
                    
                    List sortedList = snapshot.data
                      ..sort((a, b) => a['age']
                          .compareTo(b['age']));
                    
                    return ListView.builder(

Upvotes: 0

Views: 2029

Answers (1)

sventropy
sventropy

Reputation: 36

The main issue is, that _getData is (as you said) not returning a Future. Instead you deal with the future inside you .map implementation. So the function will return an empty array trial before your requests complete.

Instead, add the Future returned by each getUserInfo to an Iterable and then return the Future awaiting all of them at once.

I tried to rewrite the function without knowing the context, as it is honestly hard to tell from your question:

Future<List<dynamic>> _getData(friends) {
  final userInfoFutures = friends.map((friend) => DatabaseService().getUserInfo(
          generalServices().destructureId(friend), ['uid']));
      }));
  return Future.wait(userInfoFutures);
}

Side notes: There was a lot of clutter in your example (unused variables and parameters) which I removed.

Upvotes: 2

Related Questions