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

Flutter报错:‘String’不是‘Map<String, dynamic>’的子类型问题求助

错误原因分析

这个错误的核心是Product.fromJson()方法需要接收Map<String, dynamic>类型的参数,但你传入的response.body实际是String类型,导致类型不匹配。

常见触发场景:

  • API返回的是JSON格式的字符串,但GetX的Response未自动将其解析为Map(比如请求时未指定正确的Content-Type)
  • 你的PopularProductsRepo中封装的请求方法,返回的响应body是原始字符串而非解析后的Map结构
解决步骤

1. 先确认响应体的实际类型

在getPopularProductList方法中添加打印语句,验证response.body的类型和内容:

Future<void> getPopularProductList()async {
  Response response = await popularProductsRepo.getPopularProductList();
  if(response.statusCode==200) {
    print("response body type: ${response.body.runtimeType}");
    print("response body content: ${response.body}");
    // ... 原有代码
  }
}

运行后如果打印出String,说明确实需要手动解析。

2. 手动将JSON字符串解析为Map

修改Product.fromJson的传入参数,用jsonDecode()将字符串转为Map(记得导入dart:convert库):

import 'dart:convert';

Future<void> getPopularProductList()async {
  Response response = await popularProductsRepo.getPopularProductList();
  if(response.statusCode==200) {
    print("get products");
    _popularProductList =[];
    final Map<String, dynamic> responseData = jsonDecode(response.body);
    _popularProductList.addAll(Product.fromJson(responseData).products);
    print(_popularProductList.length);
    update();
  }else{
    print("请求失败,状态码:${response.statusCode}");
  }
}

3. 检查Repo层的请求配置

如果希望GetX自动解析JSON为Map,需要在ApiClient的请求中确保设置正确的响应类型:

// 假设你的ApiClient中的get方法
Future<Response> get(String uri) async {
  try {
    return await _dio.get(uri, options: Options(
      responseType: ResponseType.json, // 明确指定响应类型为JSON
    ));
  } catch (e) {
    return Response(statusCode: -1, statusMessage: e.toString());
  }
}

设置responseType: ResponseType.json后,Dio会自动将JSON响应解析为Map,此时response.body就是Map<String, dynamic>,无需手动jsonDecode。

修改后的完整控制器代码
import 'dart:convert';
import 'package:get/get.dart';
import 'package:food_app/models/product_model.dart';
import 'package:food_app/repos/popular_products_repo.dart';

class PopularProductController extends GetxController {
  final PopularProductsRepo popularProductsRepo;

  PopularProductController({required this.popularProductsRepo});

  List<dynamic> _popularProductList = [];

  List <dynamic> get popularProductList => _popularProductList;

  Future<void> getPopularProductList()async {
    Response response = await popularProductsRepo.getPopularProductList();
    if(response.statusCode==200) {
      print("get products");
      _popularProductList =[];
      // 兼容两种情况:body是已解析的Map或未解析的String
      final responseData = response.body is String ? jsonDecode(response.body) : response.body;
      _popularProductList.addAll(Product.fromJson(responseData).products);
      print(_popularProductList.length);
      update();
    }else{
      print("获取热门商品失败,状态码:${response.statusCode}");
    }
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 22:50:41