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

Flutter如何在单个Model中解析两种不同格式的JSON响应

问题原因

你的接口返回的data字段存在两种类型:非空时为Map<String, dynamic>对象,空时为List<dynamic>空数组,原有代码直接将data字段作为Map传入Data.fromJson,遇到空数组时就会触发类型不匹配报错。同时你把空数据场景的类型错误当成了正常空状态来处理,逻辑也不成立。

修复步骤

1. 修改UserModel的fromJson工厂方法,先做类型判断

在解析data字段前先判断类型,只有是Map的时候才解析为Data对象,否则直接赋值为null:

factory UserModel.fromJson(Map<String, dynamic> jsonData) =>
    UserModel(
      // 先判断data字段的类型
      data: jsonData['data'] is Map<String, dynamic> 
          ? Data.fromJson(jsonData['data'] as Map<String, dynamic>) 
          : null,
      meta: jsonData['meta'] is Map<String, dynamic>
          ? Meta.fromJson(jsonData['meta'] as Map<String, dynamic>)
          : null,
    );

2. 优化Data类的fromJson方法,避免内部字段为空时报错

补充对attributes、links字段的类型判断,防止接口返回字段缺失时触发异常:

factory Data.fromJson(Map<String, dynamic> json) {
  return Data(
    id: json['id'] as String?,
    attributes: json['attributes'] is Map<String, dynamic>
        ? Attributes.fromJson(json['attributes'] as Map<String, dynamic>)
        : null,
    links: json['links'] is Map<String, dynamic>
        ? Links.fromJson(json['links'] as Map<String, dynamic>)
        : null,
  );
}

3. 调整FutureBuilder的判断逻辑

修改后空数据场景会正常返回UserModel实例,只是data字段为null,不需要靠snapshot.hasError判断空状态,直接判断data字段是否为空即可:

if (snapshot.connectionState == ConnectionState.done) {
  if (snapshot.hasError) {
    // 处理真正的请求错误,比如网络不通、接口500等
    print('请求出错:${snapshot.error}');
    return const Text('请求失败');
  }
  final userModel = snapshot.data as UserModel;
  if (userModel.data == null) {
    // 空数据状态
    isDataEmpty = true;
    print('数据为空');
    return const Text('暂无数据');
  } else {
    // 有数据的正常逻辑
    isDataEmpty = false;
    print('拿到数据');
    // 渲染数据UI
  }
} else {
  // 加载中状态
  return const CircularProgressIndicator();
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.11 11:03:01