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

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');
  }
}

关键修复点

  1. 移除错误的.cast<Map<String, dynamic>>(),直接使用List<Mahalle>接收解析结果;
  2. 用mahalle.ilceAdi、mahalle.mahAdi访问对象属性,替代下标访问;
  3. 改用Map<String, List<String>>存储分组数据,避免原代码中多次遍历列表的低效操作;
  4. 添加空值判断,避免null属性导致的异常。

内容的提问来源于stack exchange,提问作者Uğur DANA

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 13:01:08