You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter解析API返回JSON时出现transform类型不匹配错误如何解决

错误产生原因

  1. 核心原因是json.decode()返回值为dynamic类型,你直接调用.map()方法时,Dart运行时阶段如果推断该值为Map类型,就会触发Map的map方法,该方法要求入参是(String, dynamic) => MapEntry类型的函数,而你传入的是(dynamic) => Product类型的转换函数,类型不匹配就抛出了该错误。即便你接口返回的是数组,没有显式强转的情况下也可能触发类型推断异常。
  2. 模型类存在字段不匹配问题:Product类中diet字段声明为非空required String,但你在fromJson方法中允许赋值为null,同时部分JSON返回中没有diet字段,会触发空安全报错。
  3. 嵌套列表转换未做类型强转:dishes和offerIds字段的转换同样直接对dynamic类型的值调用.map(),也存在同类潜在报错风险。

解决方案

第一步:修正模型类的空安全声明和转换逻辑

首先把Product类的diet字段改为可空类型,同时所有列表转换前先显式强转为List<dynamic>:

// 修正productFromJson方法,先强转成List再map
List<Product> productFromJson(String str) => List<Product>.from(
  (json.decode(str) as List<dynamic>).map((x) => Product.fromJson(x))
);

String productToJson(List<Product> data) => json.encode(List<dynamic>.from(data.map((x) => x.toJson())));

class Product {
    Product({
        required this.id,
        required this.name,
        required this.image,
        required this.description,
        required this.isFavourite,
        required this.dishes,
        this.diet, // 改为可选可空字段
    });

    String id;
    String name;
    String image;
    String description;
    bool isFavourite;
    List<Dish> dishes;
    String? diet; // 改为可空类型

    factory Product.fromJson(Map<String, dynamic> json) => Product(
        id: json["_id"],
        name: json["name"],
        image: json["image"],
        description: json["description"],
        isFavourite: json["isFavourite"],
        // 先把dishes强转为List<dynamic>再map
        dishes: List<Dish>.from((json["dishes"] as List<dynamic>).map((x) => Dish.fromJson(x))),
        diet: json["diet"],
    );

    Map<String, dynamic> toJson() => {
        "_id": id,
        "name": name,
        "image": image,
        "description": description,
        "isFavourite": isFavourite,
        "dishes": List<dynamic>.from(dishes.map((x) => x.toJson())),
        "diet": diet,
    };
}

class Dish {
    Dish({
        required this.name,
        required this.price,
        required this.offerIds,
        required this.id,
    });

    String name;
    double price;
    List<dynamic> offerIds;
    String id;

    factory Dish.fromJson(Map<String, dynamic> json) => Dish(
        name: json["name"],
        price: double.parse(json["price"].toString()),
        // 强转offerIds为List<dynamic>
        offerIds: List<dynamic>.from((json["offerIds"] as List<dynamic>).map((x) => x)),
        id: json["_id"],
    );

    Map<String, dynamic> toJson() => {
        "name": name,
        "price": price,
        "offerIds": List<dynamic>.from(offerIds.map((x) => x)),
        "_id": id,
    };
}

第二步:可选优化(异常拦截)

可以在API请求中增加类型判断,避免接口返回结构变化导致崩溃:

if (response.statusCode == 200) {
  final dynamic jsonData = json.decode(response.body);
  if (jsonData is List) {
    final List<Product> specials = productFromJson(response.body);
    _specialsList = specials;
  } else {
    _specialsList = [];
    debugPrint("接口返回结构非预期数组类型");
  }
}

内容的提问来源于stack exchange,提问作者stryker

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 20:27:01