Future.wait possible in future builder when futures return different value types?

437

Solution 1

Well, you can always use Object as the lowest common return value of those two methods:

Future.wait<Object>([firstFuture(), secondFuture()])

But you will have to cast the entries of the resulting List<Object> back to what you think they should be. Not perfect, but it would work.

Personally, I like the method you already discovered a bit more, return only the bare minimum future, a Future<void> and have it write to the respective variables inside the method. That is not perfect either, but it keeps the type safety.

Solution 2

Below answer might help you

Use FutureGroup inside the package

dependencies: async: ^2.4.1

Code:

void main()  {
  Future<String> future1 = getData(2);
  Future<String> future2 = getData(4);
  Future<String> future3 = getData(6);
  FutureGroup futureGroup = FutureGroup();
  futureGroup.add(future1);
  futureGroup.add(future2);
  futureGroup.add(future3);
  futureGroup.close();
  futureGroup.future.then((value) => {print(value)});
}

Future<String> getData(int duration) async {
  await Future.delayed(Duration(seconds: duration)); //Mock delay
  return "This a test data";
}

Output:

I/flutter ( 5866): [This a test data, This a test data, This a test data] // Called after 6 seconds.

For more reference:

https://medium.com/flutterworld/flutter-futuregroup-d79b0414eaa7

Share:
437
w461
Author by

w461

Programmed C long time ago, did some minor VBA in between and currently I am trying to create some basic home schooling apps in flutter and/or swift - just in case...

Updated on December 24, 2022

Comments

  • w461
    w461 over 1 year

    I have found answers how to wait for 2 different futures when building widgets, but these were of the same type. Example from here:

    But is there also a possibility if firstFuture() and secondFuture() return different value types - eg int and String (or different classes as in my use case)? The bool in AsyncSnapshot<List<bool>> snapshot is a challenge to me...

    FutureBuilder(
        future: Future.wait([
             firstFuture(), // Future<bool> firstFuture() async {...}
             secondFuture(),// Future<bool> secondFuture() async {...}
             //... More futures
        ]),
        builder: (
           context, 
           // List of booleans(results of all futures above)
           AsyncSnapshot<List<bool>> snapshot, 
        ){
    
           // Check hasData once for all futures.
           if (!snapshot.hasData) { 
              return CircularProgressIndicator();
           }
    
           // Access first Future's data:
           // snapshot.data[0]
    
           // Access second Future's data:
           // snapshot.data[1]
    
           return Container();
    
        }
    );
    

    I also found another answer with different types, but this apples to functions not classes

    List<Foo> foos;
    List<Bar> bars;
    List<FooBars> foobars;
    
    await Future.wait<void>([
      downloader.getFoos().then((result) => foos = result),
      downloader.getBars().then((result) => bars = result),
      downloader.getFooBars().then((result) => foobars = result),
    ]);
    
    processData(foos, bars, foobars);