1

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

Shashank Gb
  • 902
  • 1
  • 6
  • 14

2 Answers2

2

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.

Thorvald
  • 3,424
  • 6
  • 40
  • 66
  • Thankyou so much!. This worked, but I didn't understand why are you suggesting me to keep parameter from json and the factory method variable to be same. They both are of different context and we are assigning the json value to that variable... Right?. Correct me If I am wrong. And also please explain why it is not working in my approach. – Shashank Gb Aug 01 '22 at 14:58
  • 1
    @ShashankGb here's a link that explains in details what is exactly Serialization in Flutter https://docs.flutter.dev/development/data-and-backend/json – Thorvald Aug 02 '22 at 11:34
1

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'],
        );
      });
Marcel Dz
  • 2,321
  • 4
  • 14
  • 49