Flutter中'type Mahalle is not a subtype of Map<String,dynamic>'错误解决
问题:API数据按区分组时出现类型转换错误
从JSON接口拉取数据,期望处理为按ILCE_AD(区名)分组、对应MAH_AD(街区名)列表的格式。手动模拟Map数据时能得到预期输出,但对接真实API数据时出现类型转换错误:type 'Mahalle' is not a subtype of type 'Map<String, dynamic>'。
手动测试代码
void main(List<String> args) { final map = <Map<String, dynamic>>[ {'MAH_ID': 10, 'MAH_AD': 'AŞAĞI', 'ILCE_ID': 1, 'ILCE_AD': 'SARI'}, {'MAH_ID': 11, 'MAH_AD': 'YUKARI', 'ILCE_ID': 1, 'ILCE_AD': 'SARI'}, {'MAH_ID': 12, 'MAH_AD': 'SAĞ', 'ILCE_ID': 1, 'ILCE_AD': 'SARI'}, {'MAH_ID': 13, 'MAH_AD': 'SOL', 'ILCE_ID': 1, 'ILCE_AD': 'SARI'}, {'MAH_ID': 14, 'MAH_AD': 'LOW', 'ILCE_ID': 2, 'ILCE_AD': 'KIRMIZI'}, {'MAH_ID': 15, 'MAH_AD': 'MİD', 'ILCE_ID': 2, 'ILCE_AD': 'KIRMIZI'}, {'MAH_ID': 16, 'MAH_AD': 'HİGH', 'ILCE_ID': 2, 'ILCE_AD': 'KIRMIZI'}, {'MAH_ID': 17, 'MAH_AD': 'ULTRAHİGH', 'ILCE_ID': 2, 'ILCE_AD': 'KIRMIZI'} ]; final mappedValues = <Map<String, List<dynamic>>>[]; for (final element in map) { final ilceAd = element['ILCE_AD']; final mahAd = element['MAH_AD']; final contains = mappedValues.where((e) => e.keys.contains(ilceAd)).toList(); if (contains.isNotEmpty) { if (contains.first.isNotEmpty) { if (contains.first.containsKey(ilceAd)) { contains.first[ilceAd]!.add(mahAd); } } } else { mappedValues.add({ ilceAd as String: [mahAd] }); } } print(mappedValues); }
预期输出
[{SARI: [AŞAĞI, YUKARI, SAĞ, SOL]}, {KIRMIZI: [LOW, MİD, HİGH, ULTRAHİGH]}]
Mahalle模型类
import 'dart:convert'; List<Mahalle> mahalleFromJson(String str) => List<Mahalle>.from(json.decode(str).map((x) => Mahalle.fromJson(x))); String mahalleToJson(List<Mahalle> data) => json.encode(List<dynamic>.from(data.map((x) => x.toJson()))); class Mahalle { Mahalle({ this.mahId, this.mahAdi, this.mahIdDbb, this.ilceId, this.ilceAdi, this.ilceIdDbb, }); int? mahId; String? mahAdi; int? mahIdDbb; int? ilceId; String? ilceAdi; int? ilceIdDbb; factory Mahalle.fromJson(Map<String, dynamic> json) => Mahalle( mahId: json["MAH_ID"], mahAdi: json["MAH_ADI"], mahIdDbb: json["MAH_ID_DBB"], ilceId: json["ILCE_ID"], ilceAdi: json["ILCE_ADI"], ilceIdDbb: json["ILCE_ID_DBB"], ); Map<String, dynamic> toJson() => { "MAH_ID": mahId, "MAH_ADI": mahAdi, "MAH_ID_DBB": mahIdDbb, "ILCE_ID": ilceId, "ILCE_ADI": ilceAdi, "ILCE_ID_DBB": ilceIdDbb, }; }
原API请求代码
Future getApiData() async { try { final response = await http.get(url); if (response.statusCode == 200) { var result = mahalleFromJson(response.body).cast<Map<String, dynamic>>(); final mappedValues = <Map<String, List<dynamic>>>[]; for (final element in result) { final ilceAd = element['ilceAdi']; final mahAd = element["mahAdi"]; final contains = mappedValues .where((element) => element.keys.contains(ilceAd)) .toList(); if (contains.isNotEmpty) { if (contains.first.isNotEmpty) { if (contains.first.containsKey(ilceAd)) { contains.first[ilceAd]!.add(mahAd); } } } else { mappedValues.add({ ilceAd as String: [mahAd] }); } } print(mappedValues); }
报错信息
type 'Mahalle' is not a subtype of type 'Map<String, dynamic>' in type cast
错误原因
mahalleFromJson(response.body)返回的是**List<Mahalle>类型的对象列表**,但代码中试图用.cast<Map<String, dynamic>>()强制将Mahalle实例转换成Map,这是完全错误的——Mahalle是自定义类实例,不是Map,不能用下标element['ilceAdi']访问属性。
修复后的API请求代码
直接使用Mahalle类的属性访问器,同时优化分组逻辑为更简洁高效的Map<String, List<String>>:
import 'package:http/http.dart' as http; Future getApiData() async { try { final response = await http.get(url); if (response.statusCode == 200) { // 正确获取Mahalle对象列表,无需强制转换 final List<Mahalle> result = mahalleFromJson(response.body); // 使用Map直接按区名分组,结构更清晰 final Map<String, List<String>> groupedData = {}; for (final mahalle in result) { final ilceAd = mahalle.ilceAdi; final mahAd = mahalle.mahAdi; if (ilceAd != null && mahAd != null) { // 如果区名已存在,直接添加街区;不存在则初始化列表 groupedData.putIfAbsent(ilceAd, () => []).add(mahAd); } } print(groupedData); // 输出示例:{SARI: [AŞAĞI, YUKARI, SAĞ, SOL], KIRMIZI: [LOW, MİD, HİGH, ULTRAHİGH]} } } catch (e) { print('请求错误: $e'); } }
关键修复点
- 移除错误的
.cast<Map<String, dynamic>>(),直接使用List<Mahalle>接收解析结果; - 用
mahalle.ilceAdi、mahalle.mahAdi访问对象属性,替代下标访问; - 改用
Map<String, List<String>>存储分组数据,避免原代码中多次遍历列表的低效操作; - 添加空值判断,避免
null属性导致的异常。
内容的提问来源于stack exchange,提问作者Uğur DANA
相关产品推荐
相关产品推荐

