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

Flutter调用API显示数据时遇类型错误:null无法转为string

问题:API返回200但FutureBuilder报“'null' is not a subtype of type 'string'”错误

调用API获取课程包数据时,响应状态码为200 OK,但使用FutureBuilder展示数据时出现类型转换错误,错误信息为:'null' is not a subtype of type 'string'。

API返回的JSON结构示例:

{
  "status": "success",
  "code": "200",
  "data": {
    "1": {
      "id": "1",
      "id_dosen": "...",
      "kelas": "A",
      "nidn": null,
      "kode": null,
      // 其余字段省略
    }
  }
}

错误原因

  1. 响应解析逻辑错误:API返回的是包含status、code、data的完整结构,data是键值对Map,但你直接将整个响应JSON传给Datum.fromJson,导致结构不匹配。
  2. 必填字段为空:Datum类中的nidn、kode被标记为required,但API返回的这些字段可能为null,触发类型转换异常。
  3. 空值直接传入Text组件:Text(snapshot.data!.kelas)中kelas可能为null,而Text组件要求非空字符串,导致报错。

修复步骤

1. 修正API请求函数的解析逻辑

将返回类型改为Future<GetPaket>,使用GetPaket.fromJson解析完整响应:

Future<GetPaket> getPaketKuliah() async {
  String url = Constant.baseURL;
  String token = await UtilSharedPreferences.getToken();
  final response = await http.get(
    Uri.parse('$url/auth/mhs_siakad/perwalian/get_paket'),
    headers: {'Authorization': 'Bearer $token'},
  );

  print(response.statusCode);
  print(response.body);
  if (response.statusCode == 200) {
    return GetPaket.fromJson(jsonDecode(response.body));
  } else {
    throw Exception('加载课程包数据失败');
  }
}

2. 调整Datum类的必填字段

移除nidn、kode的required修饰符,允许其为null:

class Datum {
  Datum({
    this.id,
    this.idDosen,
    this.idMk,
    this.nidn, // 移除required
    this.dosen,
    this.idKelasKuliah,
    this.kelasKuliah,
    this.prodi,
    this.kelas,
    this.semester,
    this.kelompokKelas,
    this.kode, // 移除required
    this.sks,
    this.jumlahKelas,
    this.matakuliah,
    this.smt,
    this.bobotSks,
    this.rencanaPertemuan,
    this.jenisEvaluasi,
    required this.createdAt,
    required this.updatedAt,
    this.createdBy,
    this.updatedBy,
  });

  // 其余字段定义保持不变
}

3. 修正FutureBuilder的类型与数据处理

更新泛型为GetPaket,处理data为Map的结构,同时给Text组件添加空值兜底:

Container(
  child: FutureBuilder<GetPaket>(
    future: AuthProvider().getPaketKuliah(),
    builder: (context, snapshot) {
      if (snapshot.hasData) {
        // 将Map中的值转为列表,取第一个数据(根据业务逻辑调整)
        final datumList = snapshot.data!.data.values.toList();
        if (datumList.isNotEmpty) {
          return Text(datumList.first.kelas ?? '无班级信息');
        } else {
          return Text('暂无课程包数据');
        }
      } else if (snapshot.hasError) {
        return Text('加载错误: ${snapshot.error}');
      }

      return const CircularProgressIndicator();
    },
  ),
)

4. 可选优化:处理DateTime字段空值

如果API返回的created_at或updated_at可能为null,在fromJson方法中添加空值判断:

factory Datum.fromJson(Map<String, dynamic> json) => Datum(
      // ... 其余字段
      createdAt: json["created_at"] != null ? DateTime.parse(json["created_at"]) : DateTime.now(),
      updatedAt: json["updated_at"] != null ? DateTime.parse(json["updated_at"]) : DateTime.now(),
      // ... 其余字段
    );

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 03:05:33