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

Flutter中FutureBuilder获取JSON数据始终返回Null无报错如何解决

问题排查及修复方案

核心问题点

  • FutureBuilder逻辑错误:snapshot.hasData为true的分支下直接创建了空的Analysts对象,完全没有读取snapshot.data中接口返回的列表数据,空对象属性默认全为null,自然始终显示Error。
  • 模型类不符合空安全规范:Dart空安全下声明的String非空属性,构造函数却将所有参数设为可选且无默认值,逻辑矛盾会引发编译/运行异常。
  • 泛型声明语法错误:fromJson和parseAnalysis方法中Map泛型错误写为Map<"String", dynamic>,多余的引号会导致JSON解析时类型匹配失败。
  • JSON解析缺少空值处理:直接对JSON字段调用toString()、强制as String转换,若对应字段不存在或为null时会直接抛出异常,且你未在FutureBuilder中捕获错误导致问题被掩盖。
  • 缺少异常分支处理:原有FutureBuilder只判断了hasData状态,未处理加载中、请求失败的场景,无法暴露潜在的请求/解析错误。

修复后代码

1. FutureBuilder部分

FutureBuilder<List<Analysts>>(
  future: iexcloudanalysts.getData(),
  builder: (context, snapshot) {
    // 加载中状态
    if (snapshot.connectionState == ConnectionState.waiting) {
      return const CircularProgressIndicator(color: Colors.white);
    }
    // 请求错误状态
    if (snapshot.hasError) {
      return Text(
        '请求错误:${snapshot.error}',
        style: const TextStyle(color: Colors.white, fontSize: 16),
      );
    }
    // 正常返回数据
    if (snapshot.hasData && snapshot.data!.isNotEmpty) {
      // 取列表第一条数据,可根据业务需求调整取值逻辑
      Analysts analysts = snapshot.data!.first;
      return Text(
        analysts.consensusDate ?? 'Error',
        style: const TextStyle(
          color: Colors.white,
          fontSize: 32,
          fontWeight: FontWeight.bold,
        ),
      );
    }
    return const Text('无数据', style: TextStyle(color: Colors.white));
  },
)

2. Analysts模型类

class Analysts {
  // 改为可空类型适配空安全
  final String? analystCount;
  final String? consensusDate;
  final String? marketConsensus;
  final String? marketConsensusTargetPrice;

  Analysts({
    this.analystCount,
    this.consensusDate,
    this.marketConsensus,
    this.marketConsensusTargetPrice,
  });

  // 修正Map泛型,添加空值安全处理
  factory Analysts.fromJson(Map<String, dynamic> json) {
    return Analysts(
      analystCount: json['analystCount']?.toString(),
      consensusDate: json['consensusDate'] as String?,
      marketConsensus: json['marketConsensus']?.toString(),
      marketConsensusTargetPrice: json['marketConsensusTargetPrice']?.toString(),
    );
  }
}

3. 网络请求与解析部分

class IEXCloudServiceAnalysts {
  Future<List<Analysts>> getData() async{
    var url = Uri.parse("https://sandbox.iexapis.com/stable/time-series/CORE_ESTIMATES/TSLA?token=Tpk_85b3b5cdb32147d3a0fb751cc5176cdd");
    Response res = await get(url);
    // 新增状态码判断,提前抛出请求异常
    if (res.statusCode == 200) {
      return parseAnalysis(res.body);
    } else {
      throw Exception("请求失败,状态码:${res.statusCode}");
    }
  }
}

// 修正Map泛型声明
List<Analysts> parseAnalysis(String responseBody) {
  final parsed = jsonDecode(responseBody).cast<Map<String, dynamic>>();
  return parsed.map<Analysts>((json) => Analysts.fromJson(json)).toList();
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 08:57:02