Home > database >  Access list of Custom Object in FutureBuilder
Access list of Custom Object in FutureBuilder

Time:08-02

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

CodePudding user response:

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.

CodePudding user response:

In my project I faced the exact same issue. From what I read, its not directly possible to convert from an internal hashmap, I tried a lot of approaches on SO, but the following one solved my problem. I simply take the result, generate a new list where I iterate threw and access the needed data by index, and finally return the list type as the custom model, in your case Images (It's just an example, im not sure if yo access it by copy pasting my snippet, it should give you an idea what I did here):

final res = List.generate(snapshot.data.length, (i) {
        return Images (
          name: snapshot.data[i]['name'],
          url: snapshot.data[i]['campaign_image_url'],
        );
      });
  • Related