Flutter报错:'String'不是'Map<String, dynamic>'子类型,求代码修复方案
修复API调用异常:'String'类型不是'Map<String, dynamic>'的子类型
问题描述
调用API时触发异常:'String'类型不是'Map<String, dynamic>'的子类型,涉及的MeterDataModel代码如下:
class MeterDataModel { int idUnit; double startMeter; int idUtilities; double endMeter; String fotoMeter; bool flagId; DateTime createdDate; DateTime periode; int createdUser; MeterDataModel({ required this.idUnit, required this.startMeter, required this.idUtilities, required this.endMeter, required this.fotoMeter, required this.flagId, required this.createdDate, required this.periode, required this.createdUser, }); factory MeterDataModel.fromJson(Map<String, dynamic> json) => MeterDataModel( idUnit:int.parse(json["id_unit"]) , startMeter: double.parse(json["start_meter"]), idUtilities: json["id_utilities"], endMeter: double.parse(json["end_meter"]), fotoMeter: json["foto_meter"], flagId: json["flag_id"], createdDate: DateTime.parse(json["created_date"]), periode: DateTime.parse(json["periode"]), createdUser: int.parse(json["created_user"]) , ); Map<String, dynamic> toJson() => { "id_unit": idUnit, "start_meter": startMeter, "id_utilities": idUtilities, "end_meter": endMeter, "foto_meter": fotoMeter, "flag_id": flagId, "created_date": createdDate.toIso8601String(), "periode": "${periode.year.toString().padLeft(4, '0')}-${periode.month.toString().padLeft(2, '0')}-${periode.day.toString().padLeft(2, '0')}", "created_user": createdUser, }; }
结合截图信息:API返回为包裹结构(包含status、message、data字段),实际仪表数据在data节点下;部分字段返回类型为字符串(如id_unit是字符串而非数字)。
修复步骤
1. 修正API响应解析逻辑
先将API返回的JSON字符串解析为Map,再传入模型fromJson方法,且需取到正确的数据节点:
import 'dart:convert'; import 'package:http/http.dart' as http; // 示例:处理API响应 final response = await http.get(Uri.parse("你的API地址")); if (response.statusCode == 200) { final jsonResponse = jsonDecode(response.body); // 从包裹结构中取出实际数据节点 final meterDataJson = jsonResponse["data"]; // 传入模型解析 final meterData = MeterDataModel.fromJson(meterDataJson); }
若API返回数据列表,需遍历处理:
final List<dynamic> dataList = jsonResponse["data"]; final List<MeterDataModel> meterList = dataList .map((item) => MeterDataModel.fromJson(item)) .toList();
2. 增强模型类的类型转换健壮性
原模型直接使用int.parse、double.parse存在转换失败风险,修改fromJson方法增加容错处理:
factory MeterDataModel.fromJson(Map<String, dynamic> json) => MeterDataModel( idUnit: int.tryParse(json["id_unit"].toString()) ?? 0, startMeter: double.tryParse(json["start_meter"].toString()) ?? 0.0, idUtilities: int.tryParse(json["id_utilities"].toString()) ?? 0, endMeter: double.tryParse(json["end_meter"].toString()) ?? 0.0, fotoMeter: json["foto_meter"]?.toString() ?? "", flagId: json["flag_id"] is bool ? json["flag_id"] : (json["flag_id"] == "1"), createdDate: DateTime.tryParse(json["created_date"].toString()) ?? DateTime.now(), periode: DateTime.tryParse(json["periode"].toString()) ?? DateTime.now(), createdUser: int.tryParse(json["created_user"].toString()) ?? 0, );
- 用
tryParse替代parse,转换失败时返回默认值 - 对
flag_id增加类型判断,兼容数字/字符串形式的布尔值 - 对字符串字段增加空值处理,避免空指针异常
3. 验证API返回数据结构
确认API返回的data节点是单个Map对象(而非字符串或数组),若data为字符串,需排查后端接口是否存在数据返回错误。
内容的提问来源于stack exchange,提问作者Fandy Ahmad Irianto
相关产品推荐
相关产品推荐

