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

Dart HTTP转JSON遇TypeError: map[$_get] is not a function错误求助

Dart JSON转换报错:TypeError: map[$_get] is not a function

错误日志

TypeError: map[$_get] is not a function
packages/outlook/src/provider/response.dart 28:19                    fromHTTP
packages/outlook/src/provider/outlook.impl.dart 74:7                 <fn>
dart-sdk/lib/async/zone.dart 1653:54                                 runUnary
dart-sdk/lib/async/future_impl.dart 147:18                           handleValue
dart-sdk/lib/async/future_impl.dart 766:44                           handleValueCallback
dart-sdk/lib/async/future_impl.dart 795:13                           _propagateToListeners
dart-sdk/lib/async/future_impl.dart 566:5                            [_completeWithValue]
dart-sdk/lib/async/future_impl.dart 639:7                            callback
dart-sdk/lib/async/schedule_microtask.dart 40:11                     _microtaskLoop
dart-sdk/lib/async/schedule_microtask.dart 49:5                      _startMicrotaskLoop
dart-sdk/lib/_internal/js_dev_runtime/patch/async_patch.dart 166:15  <fn>

相关代码

获取主题的方法

Future<OtlResponse<List<OutlookTheme>>> getThemes() {
  return http
      .post(serverDomain,
          body: jsonEncode({'method': RequestMethods.getThemes.name,}))
      .then((http.Response resp) {
    Map<String, dynamic> body = jsonDecode(resp.body);
   
    OtlResponse<List<OutlookTheme>> response =
    OtlResponse<List<OutlookTheme>>.fromHTTP(
        map: body,
        data: List.from(body['themes'])
            .map(( themeMap) => OutlookTheme.fromMap(Map.from(themeMap)))
            .toList());

    return response;
  });
}

OtlResponse.fromHTTP工厂方法

factory OtlResponse.fromHTTP({required Map<String, dynamic> map, required T data}) {
  return OtlResponse<T>(
    success: map['success'] as bool,
    data: data,
    context: map['context'] as String,
    statusCode: map['statusCode'] as int,
    methodId: (map['method'] as String).toEnum(RequestMethods.values),
  );
}

问题

报错来自fromHTTP工厂方法及其在getThemes中的调用位置,尝试过用Map.from()处理解码后的对象但无效,求解决方法。


解决方法

这个错误本质是把非Map类型的对象当作Map操作导致的,结合你的代码,从以下几个方向排查修复:

  1. 检查toEnum扩展方法的实现
    错误栈明确指向fromHTTP的methodId行,大概率是toEnum方法内部逻辑错误。比如方法里错误地将字符串当作Map访问,就会触发这类报错。参考正确的枚举转换实现:

    extension EnumFromString<T extends Enum> on String {
      T toEnum(List<T> values) {
        return values.firstWhere(
          (e) => e.name == this,
          orElse: () => throw ArgumentError('Invalid enum value: $this'),
        );
      }
    }
    

    确保你的toEnum没有对输入字符串执行Map相关操作。

  2. 验证服务器返回的JSON结构
    先打印resp.body和body的实际内容,确认:

    • body确实是Map<String, dynamic>类型(服务器返回的是JSON对象而非数组)
    • map['success']、map['context']、map['statusCode']、map['method']字段存在且类型匹配
    • map['method']的字符串值和RequestMethods枚举的name完全一致
  3. 安全处理类型转换
    避免直接用as强制转换,改用类型判断+默认值,防止类型不匹配引发隐性错误:

    factory OtlResponse.fromHTTP({required Map<String, dynamic> map, required T data}) {
      return OtlResponse<T>(
        success: map['success'] is bool ? map['success'] : false,
        data: data,
        context: map['context'] is String ? map['context'] : '',
        statusCode: map['statusCode'] is int ? map['statusCode'] : 0,
        methodId: (map['method'] is String) 
            ? (map['method'] as String).toEnum(RequestMethods.values)
            : RequestMethods.defaultValue, // 提供默认枚举值或抛出错误
      );
    }
    
  4. 安全处理主题列表的转换
    对body['themes']先做类型校验,避免非List类型导致的后续错误:

    data: (body['themes'] is List)
        ? (body['themes'] as List)
            .map((themeMap) => themeMap is Map<String, dynamic>
                ? OutlookTheme.fromMap(themeMap)
                : throw ArgumentError('Invalid theme data: $themeMap'))
            .toList()
        : [],
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 09:30:51