How to use nested (or several) Future.builder in Flutter?

515

write another function that merges all three

Future <List<Result>> fetchResults(int mv_id1, int mv_id2, int mv_id3) async {
    List<Result> results = [];
    final result1 = await fetchResult1(mv_id1);
    final result2 = await fetchResult2(mv_id2);
    final result3 = await fetchResult3(mv_id3);
    results.addAll(result1);
    results.addAll(result2);
    results.addAll(result3);
    return results;
}

and then use it as the future of your futureBuilder

FutureBuilder<List<Result>>(
    future: fetchResults(param1, param2, param3),
    ...
Share:
515
inkwelll075
Author by

inkwelll075

Just a noob who tried to code something. Self-taught, so I can ask stupid question just in case to learn something. Obssesed with mobile (android) development. Dart/Kotlin + JetpackCompose

Updated on December 31, 2022

Comments

  • inkwelll075
    inkwelll075 over 1 year

    I have three separate get requests to the server and I want to use them at the same time in one Future.builder, but at the same time I created three separate get-requests uding Future<List> to get data from these three requests. I also saw that in order to receive parallel requests, I have to use Future.wait inside the UI thread, but this gives me this error:

    The element type 'Future<List<Result>>' can't be assigned to the list type 'Future<Result>'.
    

    How can I solve these error if I need to get three parallel request at the same time for retriving data?

    My Future:

       Future <List<Result>> fetchResult1(int mv_id) async {
          final url4 = 'http://linksecure/getRaceList.php?fmt=json&$mv_id';
          String username = '';
          String password = '';
          String basicAuth =
              'Basic ' + base64Encode(utf8.encode('$username:$password'));
          print(basicAuth);
          var response = await http.get(Uri.parse(url4), headers:<String, String>{'authorization': basicAuth});
          var jsonResponse = convert.jsonDecode(response.body) as List;
          return jsonResponse.map((e) => Result.fromJson(e)).toList();
        }
     Future <List<Result>> fetchResult2(int mv_id) async {
          final url4 = 'http://linksecure/getBooks.php?fmt=json&$mv_id';
          String username = '';
          String password = '';
          String basicAuth =
              'Basic ' + base64Encode(utf8.encode('$username:$password'));
          print(basicAuth);
          var response = await http.get(Uri.parse(url4), headers:<String, String>{'authorization': basicAuth});
          var jsonResponse = convert.jsonDecode(response.body) as List;
          return jsonResponse.map((e) => Result.fromJson(e)).toList();
        }
     Future <List<Result>> fetchResult3(int mv_id) async {
          final url4 = 'http://linksecure/getBookList.php?fmt=json&$mv_id';
          String username = '';
          String password = '';
          String basicAuth =
              'Basic ' + base64Encode(utf8.encode('$username:$password'));
          print(basicAuth);
          var response = await http.get(Uri.parse(url4), headers:<String, String>{'authorization': basicAuth});
          var jsonResponse = convert.jsonDecode(response.body) as List;
          return jsonResponse.map((e) => Result.fromJson(e)).toList();
        }
    

    My Futurebuilder inside UI:

    class Results extends StatelessWidget {
      final int mrId;
    
      const Results({Key key, this.mrId}) : super(key: key);
      @override
      Widget build(BuildContext context) {
        return Scaffold(
            appBar: AppBar(),
            body: FutureBuilder<List<Result>>(
                future:
                    Future.wait([fetchResult1(0), fetchResult2(), fetchResult3()]),
                builder: (context, snapshot) {
                  if (snapshot.connectionState == ConnectionState.none &&
                      snapshot.hasData == null) {
                    return Container();
                  };
                  return ListView.builder(
                      itemCount: snapshot.data.length,
                      itemBuilder: (context, index) {
                        Result project = snapshot.data[index];
                        return ListTile(
                          title: Text(project.rlLaststation),
                          subtitle: Text(project.rlLaststation),
                        );
                      });
                }));
      }
    }
    

    Also i think I need to put here my model because it seems like I did something wrong in here, so my models is:

    List<Result> result1FromJson(String str) => List<Result>.from(json.decode(str).map((x) => Result.fromJson(x)));
    
    String result1ToJson(List<Result> data) => json.encode(List<dynamic>.from(data.map((x) => x.toJson())));
    
        class Result {
          Result({
            this.rlId,
            this.mrId,
            this.rlRacetype,
            this.rlFirststationId,
            this.rlLaststationId,
            this.rlFirststation,
            this.rlFirststationEn,
            this.rlLaststation,
            this.rlLaststationEn,
            this.stopList,
          });
        
          String rlId;
          int mrId;
          String rlRacetype;
          String rlFirststationId;
          String rlLaststationId;
          String rlFirststation;
          String rlFirststationEn;
          String rlLaststation;
          String rlLaststationEn;
          List<StopList> stopList;
        
          factory Result.fromJson(Map<String, dynamic> json) => Result(
            rlId: json["rl_id"],
            mrId: json["mr_id"],
            rlRacetype: json["rl_racetype"],
            rlFirststationId: json["rl_firststation_id"],
            rlLaststationId: json["rl_laststation_id"],
            rlFirststation: json["rl_firststation"],
            rlFirststationEn: json["rl_firststation_en"],
            rlLaststation: json["rl_laststation"],
            rlLaststationEn: json["rl_laststation_en"],
            stopList: List<StopList>.from(json["stopList"].map((x) => StopList.fromJson(x))),
          );
        
          Map<String, dynamic> toJson() => {
            "rl_id": rlId,
            "mr_id": mrId,
            "rl_racetype": rlRacetype,
            "rl_firststation_id": rlFirststationId,
            "rl_laststation_id": rlLaststationId,
            "rl_firststation": rlFirststation,
            "rl_firststation_en": rlFirststationEn,
            "rl_laststation": rlLaststation,
            "rl_laststation_en": rlLaststationEn,
            "stopList": List<dynamic>.from(stopList.map((x) => x.toJson())),
          };
        }
        
        class StopList {
          StopList({
            this.rcOrderby,
            this.stId,
            this.stTitle,
            this.stTitleEn,
            this.rcKkp,
          });
        
          int rcOrderby;
          int stId;
          String stTitle;
          String stTitleEn;
          RcKkp rcKkp;
        
          factory StopList.fromJson(Map<String, dynamic> json) => StopList(
            rcOrderby: json["rc_orderby"],
            stId: json["st_id"],
            stTitle: json["st_title"],
            stTitleEn: json["st_title_en"],
            rcKkp: rcKkpValues.map[json["rc_kkp"]],
          );
    
    • pskink
      pskink over 2 years
      you need to use snapshot.data[0], snapshot.data[1] and snapshot.data[2]
    • inkwelll075
      inkwelll075 over 2 years
      @pskink Hi, thanks you, where can I put it? I mean in Future.wait([future: snapshot.data[0], snapshot.data[1])
    • pskink
      pskink over 2 years
      inside builder: