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

Flutter从API获取数据后报错:期望String类型却得到TypeErrorImpl

Flutter JSON解析类型错误修复:Expected a value of type 'String', but got one of type 'TypeErrorImpl'

问题现象

请求API成功获取部门JSON响应,但处理响应时抛出错误:

Uncaught (in promise) Error: Expected a value of type 'String', but got one of type 'TypeErrorImpl'

API返回的JSON响应

{
    "success": true,
    "data": [
        {
            "id": "56c8b5f8-7f74-4f0c-9fc0-9a3c411bc3a4",
            "image": "http://127.0.0.1:8000/media/api/uploads/departments/2023/03/14/child_yk4u2KO.png",
            "name": "Education And Child Development",
            "slug": "education-and-child-development",
            "created_at": "2023-02-23T14:51:39Z",
            "updated_at": "2023-03-14T14:24:10.699998Z"
        }
    ],
    "message": "Departments successfuly retrieved"
}

问题代码分析

Department实体类(department.dart)

class Department {
  String id;
  String image;
  String name;
  String slug;
  Department({
    this.id,
    this.image,
    this.name,
    this.slug,
  });
  Department.fromJson(Map<String, dynamic> json) {
    id = json['id'].toString();
    image = json['image'] != null ? json['image'] : null;
    name = json['name'] != null ? json['name'] : null;
    slug = json['slug'];
  }
  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = new Map<String, dynamic>();
    data['id'] = this.id;
    data['image'] = this.image;
    data['name'] = this.name;
    data['slug'] = this.slug;
    return data;
  }
}

数据获取函数

Future<Stream<Department>> getSchoolDepartments() async {
  final String url =
      '${GlobalConfiguration().getString('api_base_url')}departments';
  final client = new http.Client();
  try {
    final streamedRest = await client.send(http.Request('get', Uri.parse(url)));
    print("Status code : " + streamedRest.statusCode.toString());
    return streamedRest.stream
        .transform(utf8.decoder)
        .transform(json.decoder)
        .map((data) => Helper.getData(data))
        .expand((data) => (data as List))
        .map((data) {
          print("data : " + data); // 错误根源:data是Map类型,无法直接与字符串拼接
          return Department.fromJson(data);
        });
  } on Exception catch (e) {
    print(e);
  }
}

数据处理函数(school_controller.dart)

void listenForDepartments() async {
  print("starting departments stream");
  final Stream<Department> stream = await getSchoolDepartments();
  stream.listen((Department _department) {
    setState(() => departments.add(_department));
  }, onError: (a) {
    print("Failed to add department : " + a); // 错误:a是Error类型,不能直接拼接字符串
  }, onDone: () {});
}

错误根源

  1. 数据获取函数的print语句:print("data : " + data); 中的data是Map<String, dynamic>类型,直接与字符串用+拼接触发类型不匹配错误,这是抛出TypeErrorImpl的直接原因。
  2. 错误处理的字符串拼接:onError回调里的print("Failed to add department : " + a);,a是Error对象,无法直接与字符串拼接。

修复方案

1. 修正数据获取函数的print语句

将Map类型的data转为字符串后再打印:

.map((data) {
  print("data : ${data.toString()}"); // 用字符串插值转换为String
  return Department.fromJson(data);
});

2. 修正错误处理中的字符串拼接

用字符串插值自动转换Error对象为字符串:

onError: (a) {
  print("Failed to add department : $a");
},

3. 可选:优化实体类空安全处理(适配Flutter空安全版本)

给字段添加空安全修饰符,避免潜在空指针问题:

class Department {
  String? id;
  String? image;
  String? name;
  String? slug;
  Department({
    this.id,
    this.image,
    this.name,
    this.slug,
  });
  Department.fromJson(Map<String, dynamic> json) {
    id = json['id']?.toString(); // 空安全访问
    image = json['image'];
    name = json['name'];
    slug = json['slug'];
  }
  // toJson方法保持不变
}

验证修复

运行代码后,API响应的JSON数据会被正确解析为Department对象并添加到departments列表中,不再抛出类型错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 09:37:08