从json颤振中获取数组

Posted

技术标签:

【中文标题】从json颤振中获取数组【英文标题】:Get array from json flutter 【发布时间】:2021-03-21 15:57:53 【问题描述】:

试图获取植物信息并找到https://trefle.io/ Api,要在我的flutter应用程序中使用,我需要植物信息列表,所以我找到了这样的json结构;

我正在尝试从 api 数组中获取数据并在我的 ListView.builder 中实现它,但出现错误;

类型“Future”不是类型“Map”的子类型

那么从json中获取数组数据最有效的方法是什么

列表视图

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),
                              ),
                            );
                          ),

获取数据

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

    return decoded;
  

植物

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;
  

数据

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;
  

解决

在下面添加了这个功能

 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 
  

更改了 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;
  

【问题讨论】:

我使用动态或有时根本不使用类型def。 【参考方案1】:
    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,
  ;

响应 = 等待 http.get(url); final plant = plantFromJson(response.body) // 获取解析数据

【讨论】:

创建了方法,并尝试了 plant=plantFromJson(response.body) 没有任何改变 final plant=plantFromJson(response.body) 然后使用 plant.data ,您可以在其中获取所有数据 你得到什么 plant=plantFromJson(response.body) ;打印(植物。数据); “植物”实例【参考方案2】:

这就是我想说的话

 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<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());
        
      );

【讨论】:

用future包裹,将解码后的数据作为future传递,同样的错误再次发生 没试过,但用其他方式解决了问题,正如您现在在我的问题中看到的那样,无论如何感谢您的帮助。

以上是关于从json颤振中获取数组的主要内容,如果未能解决你的问题,请参考以下文章

如何继续在颤振中接收 JSON 数组并解析它?

如何在颤振应用程序中获取 JSON 数据?

试图从世界时间 api 颤振发出 json 请求

如何从 Flutter 中的 JSON 文件中获取所有命令 id?

无法从 api 获取数据,Future 总是返回 null - 颤振

颤振获取密钥 - Json