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

Flutter调用API触发Unexpected null value错误,请求排查

Flutter调用API时出现Unexpected null value错误的解决方案

问题描述

调用API获取单个坐骑数据时,持续触发Unexpected null value错误,无法正常加载数据。API返回的JSON结构如下:

{
  "id": 257,
  "name": "Island Eggplant Knight",
  "description": "Summon forth your island Eggplant Knight, an oversized vegetable embodiment of chivalry.",
  "enhanced_description": "Hailing from the selfsame land as the Tomato King, the Eggplant Knight shared a crate with the sovereign when they were shipped out. However, he fell overboard when the vessel encountered rough seas, and drifted for days before being deposited on a desert island. Among other feats, he prides himself on having played a key role in the founding of the West Mandra Empire.",
  "tooltip": "I thought ye were a feral turnip, a murderous eggplant, or summat like that!    - Tiny Trader",
  "movement": "Terrestrial",
  "seats": 1,
  "order": 240,
  "order_group": 99,
  "patch": "6.2",
  "item_id": null,
  "tradeable": false,
  "owned": "3.9%",
  "image": "https://ffxivcollect.com/images/mounts/large/257.png",
  "icon": "https://ffxivcollect.com/images/mounts/small/257.png",
  "bgm": "https://ffxivcollect.com/music/BGM_Ride_MJI.ogg",
  "sources": [
    {
      "type": "Purchase",
      "text": "12,000 Seafarer's Cowries",
      "related_type": null,
      "related_id": null
    }
  ]
}

错误核心原因

  1. API响应格式与解析逻辑不匹配:该API返回的是单个对象,但你的模型解析代码强制将其转为List,导致json.decode(str).map执行时因单个对象无map方法抛出空值异常。
  2. 服务层返回类型错误:RemoteService.getPosts声明返回Future<List<FinalApi>>,但实际应返回单个FinalApi实例。
  3. UI层依赖错误数据类型:Home页面用finalApi!.length获取列表长度,但finalApi实际是单个对象,强制解包触发空值错误。

修复步骤

1. 修改模型解析代码

将列表解析改为单个对象解析:

// 替换原有的列表解析方法
FinalApi finalApiFromJson(String str) => FinalApi.fromJson(json.decode(str));

String finalApiToJson(FinalApi data) => json.encode(data.toJson());

2. 修正RemoteService代码

调整返回类型并修正解析逻辑:

class RemoteService {
  Future<FinalApi> getPost() async {
    var client = http.Client();
    var uri = Uri.parse('https://ffxivcollect.com/api/mounts/257');
    var response = await client.get(uri);
    if (response.statusCode == 200) {
      var json = response.body;
      return finalApiFromJson(json);
    }
    throw Exception('请求失败');
  }
}

3. 调整Home页面UI代码

因数据为单个对象,无需使用ListView.builder,直接展示数据(建议搭配FutureBuilder处理异步加载):

Widget build(BuildContext context) {
  return Scaffold(
    appBar: AppBar(title: const Text('')),
    body: FutureBuilder<FinalApi>(
      future: RemoteService().getPost(),
      builder: (context, snapshot) {
        if (snapshot.connectionState == ConnectionState.waiting) {
          return const Center(child: CircularProgressIndicator());
        } else if (snapshot.hasError) {
          return Center(child: Text('错误: ${snapshot.error}'));
        } else if (snapshot.hasData) {
          return Container(child: Text(snapshot.data!.description));
        } else {
          return const Center(child: Text('无数据'));
        }
      },
    ),
  );
}

4. 优化模型类型安全性(可选)

将dynamic itemId改为int? itemId,明确字段可为空,增强代码健壮性:

class FinalApi {
  // ...其他字段
  int? itemId;

  FinalApi({
    // ...其他required参数
    required this.itemId,
    // ...其他参数
  });

  factory FinalApi.fromJson(Map<String, dynamic> json) => FinalApi(
        // ...其他字段赋值
        itemId: json["item_id"],
        // ...其他赋值
      );
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 23:35:19