You need to enable JavaScript to run this app. Flutter调用REST API解析响应时报List<dynamic>不是Map<String,dynamic>子类型错误
优惠活动
大模型
产品
解决方案
定价
更多

Flutter调用REST API解析响应时报List<dynamic>不是Map<String,dynamic>子类型错误

错误根因

实体类结构与接口实际返回结构不匹配,核心问题有2个:

  1. 接口返回的data字段是List数组类型,但你在MealJSON类中将data声明为单个MealboxListing对象(本质是Map<String, dynamic>),赋值时触发了List转Map的类型错误
  2. 接口返回的add_ons是UUID为key、附加项对象为value的键值对结构,但你在MealboxListing类中将addOns声明为单个AddOn对象,后续启用该字段解析也会触发类型错误

修复步骤

  • 修改MealJSON类结构

将data字段类型改为List<MealboxListing>,同步调整解析逻辑:

class MealJSON {
  int code;
  List<MealboxListing> data; // 改这里,从单个对象改为列表

  MealJSON({this.code, this.data});

  MealJSON.fromJson(Map<String, dynamic> json) {
    code = json['code'];
    // 改这里,遍历数组解析为MealboxListing列表
    data = (json['data'] as List<dynamic>?)
        ?.map((e) => MealboxListing.fromJson(e as Map<String, dynamic>))
        .toList();
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = new Map<String, dynamic>();
    data['code'] = this.code;
    if (this.data != null) {
      data['data'] = this.data.map((e) => e.toJson()).toList();
    }
    return data;
  }
}
  • 修改MealboxListing类

调整addOns字段类型,补全解析逻辑,同时优化数值转换避免报错:

class MealboxListing {
  // 改这里,从单个AddOn改为键值对Map
  Map<String, AddOn> addOns;
  bool availability;
  double averageRating;
  String cityLive;
  String deliveryDate;
  String description;
  List<String> imageDetails;
  String kitchenDetails;
  String listingId;
  int numberOfMeals;
  String origin;
  String title;
  List<String> preferences;
  List<String> tag;
  List<String> included;

  MealboxListing(
      {this.addOns,
      this.availability,
      this.averageRating,
      this.cityLive,
      this.deliveryDate,
      this.description,
      this.imageDetails,
      this.kitchenDetails,
      this.listingId,
      this.numberOfMeals,
      this.origin,
      this.title,
      this.preferences,
      this.tag,
      this.included});

  MealboxListing.fromJson(Map<String, dynamic> json) {
    // 补全add_ons解析逻辑
    addOns = (json['add_ons'] as Map<String, dynamic>?)?.map(
      (key, value) => MapEntry(
        key,
        AddOn.fromJson(value as Map<String, dynamic>),
      ),
    );
    availability = json['available'];
    averageRating = json['average_rating'];
    cityLive = json['city_live'];
    deliveryDate = json['delivery_on'];
    description = json['description'];
    imageDetails = json['img_url'].cast<String>();
    kitchenDetails = json['kitchen'];
    listingId = json['listing_id'];
    // 优化数值转换,兼容int和字符串两种返回格式
    numberOfMeals = json['no_of_meals'] is int 
        ? json['no_of_meals'] 
        : int.parse(json['no_of_meals'].toString());
    origin = json['origin'];
    title = json['title'];
    preferences = json['preferences'].cast<String>();
    tag = json['tags'].cast<String>();
    included = json['whats_included'].cast<String>();
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = new Map<String, dynamic>();
    if (this.addOns != null) {
      data['add_ons'] = this.addOns.map((key, value) => MapEntry(key, value.toJson()));
    }
    data['available'] = this.availability;
    data['average_rating'] = this.averageRating;
    data['city_live'] = this.cityLive;
    data['delivery_on'] = this.deliveryDate;
    data['description'] = this.description;
    data['img_url'] = this.imageDetails;
    data['kitchen'] = this.kitchenDetails;
    data['listing_id'] = this.listingId;
    data['no_of_meals'] = this.numberOfMeals;
    data['origin'] = this.origin;
    data['title'] = this.title;
    data['preferences'] = this.preferences;
    data['tags'] = this.tag;
    data['whats_included'] = this.included;
    return data;
  }
}
  • 修改API调用逻辑

适配返回的列表结构:

// 改返回值类型为列表
static Future<List<MealboxListing>?> getData() async {
    String vendorId = await secureStorage.read(key: "cust_id");
    String token = await secureStorage.read(key: "access_token");
    try {
      var res = await http.get(
        Uri.parse("你的接口地址"),
        headers: {
          "Content-Type": "application/json",
          'Authorization': 'Bearer $token'
        },
      );
      if (res.statusCode == 200) {
        MealJSON mealJSON = mealFromJson(res.body);
        // mealJSON.data就是解析完成的餐盒列表
        print(mealJSON.data?.first.description);
        return mealJSON.data;
      }
    } catch (e) {
      print(e.toString());
      return null;
    }
  }

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.16 01:36:10