I am working on a complex web application in which from time to time, I need to fetch data from backend API. Sometimes, I need to call 2 future functions in Future Builder to use their values. However, it makes code messy because for each FutureBuilder I need to check, if it has data or not and return the widget. It looks like this.
return FutureBuilder<object>(
future: func1(),
builder:(context, AsyncSnapshot<object> snapshot1){
if(snapshot1.hasData){
return FutureBuilder<object>(
future: func2(),
builder:(context, AsyncSnapshot<object> snapshot2){
if(snapshot2.hasData){
return widget;
}else{
return CircularProgressIndicator();
}
}
),
}else{
return CircularProgressIndicator();
}
}
);
Is there any other simpler way? where I can use only one FutureBuilder so that I do not have to return widgets i.e (CircularProgressIndicator)each time. Thanks.
CodePudding user response:
First create result model class like this:
class ResultModel{
final object1 result1;
final object2 result2;
ResultModel({required this.result1, required this.result2});
}
then you can create new future
like this:
Future<ResultModel> _newFuture() async {
final results = await Future.wait([func1(), func2()]);
return ResultModel(result1: results[0], result2: results[1]);
}
then pass this to single FutureBuilder
:
FutureBuilder<ResultModel>(
future: _newFuture(),
builder:(context, AsyncSnapshot<ResultModel> snapshot1){
if(snapshot1.hasData){
return return widget;
}else{
return CircularProgressIndicator();
}
}
)
CodePudding user response:
1/. If func1 and func2 are independent, you can call it same time by using
Future.wait https://api.flutter.dev/flutter/dart-async/Future/wait.html
2/. If your func2 depend on func1. Write 1 custom func and use it in your future builder:
func1AndFunc2() async {
var result = await func1();
// check result has data
if (result != null) {
return func2();
}
}
CodePudding user response:
No need to complicate with ResultModel class as the accepted answer suggests. What if we need 3 futures to run? Create the new model for 3? And 4?
Simple solution is below. Note that you can use List if functions return different types, and you could cast accordingly when reading the value.
FutureBuilder<List<dynamic>>(
future: Future.wait([func1(), func2()]),
builder:(context, AsyncSnapshot<ResultModel> snapshot1){
if(snapshot1.hasData){
var result1=snapshot1.data[0];
var result1=snapshot1.data[1];
return return widget;
}else{
return CircularProgressIndicator();
}
}
)