Search code examples
flutterdartsnapshotflutter-futurebuilder

Access list of Custom Object in FutureBuilder


I have a method, fetches some data from url and gets json array response like

Future<List<Images>> getData(String url) async {
    var response = await http.get(Uri.parse(url));
    return List<Images>.from(jsonDecode(response.body).map((x) => Images.fromJSON(x)));
}
response.body => [{"name":"img1","campaign_image_url":"http:\/\/xx.xxx.xxx.xxx\/development\/img1.jpg"},{"name":"img2","campaign_image_url":"http:\/\/xx.xxx.xxx.xxx\/development\/img2.jpg"}]

I have a Custom Object Called Images like

class Images {
  final String name;
  final String url;

  Images({required this.name, required this.url});

  Images.fromJSON(Map<String, String> json)
      : name = json['name']!,
        url = json['campaign_image_url']!;
}

I am using FutureBuilder to call a method getData() and loads data dynamically like

FutureBuilder<List<Images>>(
  future: getData(url),
  builder: (ctx, AsyncSnapshot<List<Images>> snapshot){
    if (snapshot.hasError) print(snapshot.error); //type '_InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'Map<String, String>'
    if (snapshot.hasData) print(snapshot.data);
    return Container();
  }
)

Not able to get the data in FutureBuilder using snapshot and it is throwing snapshot error like type '_InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'Map<String, String>'

I tried these

I am expecting something like List<Images> lst = snapshot.data. But Something is missing and throwing an error, I can't figure it out


Solution

  • Try updating your Images class to the following:

    import 'dart:convert';
    
    Images imagesFromJson(String str) =>   Images.fromJson(json.decode(str));
    
    String imagesToJson(Images data) => json.encode(data.toJson());
    
    class Images {
        Images({
            required this.name,
            required this.url,
        });
    
        String name;
        String url;
    
        factory Images.fromJson(Map<String, dynamic> json) => Images(
            name: json["name"],
            // the json["url"] should be exactly how you receive it from your backend
            url: json["url"],
        );
    
        Map<String, dynamic> toJson() => {
            "name": name,
            "url": url,
        };
    }
    

    Then use the Images.fromJson() as you normally would.