2

Trying to get plant info and found https://trefle.io/ Api, to use in my flutter app, i need list of plant infos, so i found a json structure like this;

enter image description here

I'm trying fetch data from api array and implement it my ListView.builder, but i'm getting error;

type 'Future' is not a subtype of type 'Map<String, dynamic>'

So What's the most efficient way of fetching array data from json

List View

ListView.builder(
                          scrollDirection: Axis.horizontal,
                          itemCount: 10,
                          itemBuilder: (BuildContext context, int index) {
                            Plant plant = Plant.fromJson(decodedData);
                            Data data = plant.data[index];
                            Container(
                              child: Image(
                                image: NetworkImage(data.imageUrl),
                              ),
                            );
                          }),

FETCH DATA

  Future<dynamic> fetchData(String url, bool asyncCall) async {
    asyncCall = true;
    response = await http.get(url);
    decoded = json.encode(response.body);

    return decoded;
  }

PLANT

class Plant {
  List<Data> data;

  Plant({this.data});

  Plant.fromJson(Map<String, dynamic> json) {
    if (json['data'] != null) {
      data = new List<Data>();
      json['data'].forEach((v) {
        data.add(new Data.fromJson(v));
      });
    }
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = new Map<String, dynamic>();
    if (this.data != null) {
      data['data'] = this.data.map((v) => v.toJson()).toList();
    }

    return data;
  }
}

DATA

class Data {
  int id;
  String commonName;
  String slug;
  String scientificName;
  int year;
  String bibliography;
  String author;
  String status;
  String rank;
  String familyCommonName;
  int genusId;
  String imageUrl;
  List<String> synonyms;
  String genus;
  String family;

  Data({
    this.id,
    this.commonName,
    this.slug,
    this.scientificName,
    this.year,
    this.bibliography,
    this.author,
    this.status,
    this.rank,
    this.familyCommonName,
    this.genusId,
    this.imageUrl,
    this.synonyms,
    this.genus,
    this.family,
  });

  Data.fromJson(Map<String, dynamic> json) {
    id = json['id'];
    commonName = json['common_name'];
    slug = json['slug'];
    scientificName = json['scientific_name'];
    year = json['year'];
    bibliography = json['bibliography'];
    author = json['author'];
    status = json['status'];
    rank = json['rank'];
    familyCommonName = json['family_common_name'];
    genusId = json['genus_id'];
    imageUrl = json['image_url'];
    synonyms = json['synonyms'].cast<String>();
    genus = json['genus'];
    family = json['family'];
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = new Map<String, dynamic>();
    data['id'] = this.id;
    data['common_name'] = this.commonName;
    data['slug'] = this.slug;
    data['scientific_name'] = this.scientificName;
    data['year'] = this.year;
    data['bibliography'] = this.bibliography;
    data['author'] = this.author;
    data['status'] = this.status;
    data['rank'] = this.rank;
    data['family_common_name'] = this.familyCommonName;
    data['genus_id'] = this.genusId;
    data['image_url'] = this.imageUrl;
    data['synonyms'] = this.synonyms;
    data['genus'] = this.genus;
    data['family'] = this.family;

    return data;
  }
}

To Solve

Added this func below

 Plant plant;
  Future<void> getPlant() async {
    String url =
        'https://trefle.io/api/v1/plants?token=jAEYseuuPFUlUss9QcNOefanIBG_fb83mkXdaRDIu8w';
    Map<String, String> header = {"Content-type": "application/json"};
    // make GET request
    var response = await http.get(url, headers: header);
    // check the status code for the result
    if (response.statusCode == 200) {
      setState(() {
        plant = plantFromJson(response.body);
      });
    } else {}
  }

changed fetchData

 Future<Plant> fetchData(String url, bool asyncCall) async {
    asyncCall = true;
    response = await http.get(url);

    final plant = plantFromJson(response.body);
    print(plant);
    print(plant.data);
    print(plant.data[0].imageUrl);
    return plant;
  }
1
  • I use dynamic or sometimes no type def at all. Commented Dec 10, 2020 at 9:18

2 Answers 2

2
    import 'dart:convert';

Plant plantFromJson(String str) => Plant.fromJson(json.decode(str));

String plantToJson(Plant data) => json.encode(data.toJson());

class Plant {
  Plant({
    this.data,
    this.links,
    this.meta,
  });

  List<Data> data;
  PlantLinks links;
  Meta meta;

  factory Plant.fromJson(Map<String, dynamic> json) => Plant(
    data: List<Data>.from(json["data"].map((x) => Data.fromJson(x))),
    links: PlantLinks.fromJson(json["links"]),
    meta: Meta.fromJson(json["meta"]),
  );

  Map<String, dynamic> toJson() => {
    "data": List<dynamic>.from(data.map((x) => x.toJson())),
    "links": links.toJson(),
    "meta": meta.toJson(),
  };
}

class Data {
  Data({
    this.author,
    this.bibliography,
    this.commonName,
    this.family,
    this.familyCommonName,
    this.genus,
    this.genusId,
    this.id,
    this.links,
    this.plantId,
    this.rank,
    this.scientificName,
    this.slug,
    this.status,
    this.synonyms,
    this.year,
  });

  String author;
  String bibliography;
  dynamic commonName;
  String family;
  String familyCommonName;
  String genus;
  int genusId;
  int id;
  DatumLinks links;
  int plantId;
  String rank;
  String scientificName;
  String slug;
  String status;
  List<String> synonyms;
  int year;

  factory Data.fromJson(Map<String, dynamic> json) => Data(
    author: json["author"],
    bibliography: json["bibliography"],
    commonName: json["common_name"],
    family: json["family"],
    familyCommonName: json["family_common_name"] == null ? null : json["family_common_name"],
    genus: json["genus"],
    genusId: json["genus_id"],
    id: json["id"],
    links: DatumLinks.fromJson(json["links"]),
    plantId: json["plant_id"],
    rank: json["rank"],
    scientificName: json["scientific_name"],
    slug: json["slug"],
    status: json["status"],
    synonyms: List<String>.from(json["synonyms"].map((x) => x)),
    year: json["year"],
  );

  Map<String, dynamic> toJson() => {
    "author": author,
    "bibliography": bibliography,
    "common_name": commonName,
    "family": family,
    "family_common_name": familyCommonName == null ? null : familyCommonName,
    "genus": genus,
    "genus_id": genusId,
    "id": id,
    "links": links.toJson(),
    "plant_id": plantId,
    "rank": rank,
    "scientific_name": scientificName,
    "slug": slug,
    "status": status,
    "synonyms": List<dynamic>.from(synonyms.map((x) => x)),
    "year": year,
  };
}

class DatumLinks {
  DatumLinks({
    this.genus,
    this.plant,
    this.self,
  });

  String genus;
  String plant;
  String self;

  factory DatumLinks.fromJson(Map<String, dynamic> json) => DatumLinks(
    genus: json["genus"],
    plant: json["plant"],
    self: json["self"],
  );

  Map<String, dynamic> toJson() => {
    "genus": genus,
    "plant": plant,
    "self": self,
  };
}

class PlantLinks {
  PlantLinks({
    this.first,
    this.last,
    this.next,
    this.self,
  });

  String first;
  String last;
  String next;
  String self;

  factory PlantLinks.fromJson(Map<String, dynamic> json) => PlantLinks(
    first: json["first"],
    last: json["last"],
    next: json["next"],
    self: json["self"],
  );

  Map<String, dynamic> toJson() => {
    "first": first,
    "last": last,
    "next": next,
    "self": self,
  };
}

class Meta {
  Meta({
    this.total,
  });

  int total;

  factory Meta.fromJson(Map<String, dynamic> json) => Meta(
    total: json["total"],
  );

  Map<String, dynamic> toJson() => {
    "total": total,
  };
}

response = await http.get(url); final plant = plantFromJson(response.body) // to get parsed data

Sign up to request clarification or add additional context in comments.

4 Comments

created method, and tried plant=plantFromJson(response.body) nothing changed
final plant=plantFromJson(response.body) then use plant.data , where you get all data
What you get plant=plantFromJson(response.body) ; print(plant.data);
Instance of 'Plant'
1

Here what i want to say exactly

 Future<Plant> fetchData(String url) async {
final response = await http.get(
    "TYPE_YOUR_HTTP",
    
if (response.statusCode == 200) {
  return Plant.fromJson(jsonDecode(response.body));//change here
} else {
  throw Exception("Failed to load data");
}

}

//Future Builder

Future<Plant> plantList;
  plantList = FetchData.fetchdata(data);//create a future object and call your fetch data funct with it
return FutureBuilder<Plant>(
      future: plantList,/
      builder: (context, snapshot) {
        if (snapshot.connectionState == ConnectionState.done) {
          if (snapshot.data == null) {
            return Center(
              child: Text("No result "),
            );
          } else {
            return ListView.builder(
              itemCount: snapshot.data.plant.length,
              itemBuilder: (BuildContext context, int index) {
                return ListTile(
                    //Create ListTile here or something that you prefer);
              },
            );
          }
        } else if (snapshot.connectionState == ConnectionState.none) {
          return Center(child: Text(snapshot.error));
        } else {
          return Center(child: CircularProgressIndicator());
        }
      });

2 Comments

wrapped with future, passed decoded data as future, and same error occurs again
Didn't try it but solved issue with other way as you can see in my question now, thanks for your help anyway.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.