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
相关产品推荐
相关产品推荐

