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

Viewed 617

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);
2 Answers

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.

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

Related