Flutter Bloc处理API数据时List与Map类型不匹配错误排查
错误信息:
List<dynamic> 不是 Map<String, dynamic> 的子类型 问题根源
API返回的ResponsePacket是数组类型(对应Dart的List<dynamic>),但现有代码存在两个核心错误:
- 直接将整个
ResponsePacket数组传入仅接受单个Map<String, dynamic>的OutletCityListModel.fromJson方法 - 把存储多个模型的
List<OutletCityListModel>强制转换为单个OutletCityListModel,传递给状态类
解决方案
1. 修正Bloc的数据解析逻辑
修改OutletCityCubit中的outletCityList方法,正确遍历数组并转换模型,同时修正状态传递的类型:
import 'dart:developer'; import 'package:flutter_bloc/flutter_bloc.dart'; import '../../../ApiManager/api_manager.dart'; import '../../../Models/outlet_city_list_model.dart'; import 'outlet_city_state.dart'; class OutletCityCubit extends Cubit<OutletCityState> { ApiManager _apiManager = ApiManager(); OutletCityCubit() : super(OutletCityInitialState()) {} outletCityList() async { List<OutletCityListModel> outletCityListData =[]; emit(OutletCityLoadingState()); await _apiManager.outletCityListApi().then((val) { log("outletCityList:: $val"); emit(OutletCityLoadingOffState()); if (val["StatusCode"] == 200) { log("data::::: ${val["ResponsePacket"]}"); // 遍历ResponsePacket数组,逐个转换为模型 List<dynamic> responseList = val["ResponsePacket"]; for(var item in responseList) { outletCityListData.add(OutletCityListModel.fromJson(item)); } // 传递模型列表给状态,取消错误的强制转换 emit(OutletCityCodeSentState(outletCityListData)); } else if (val["StatusCode"] == 400) { emit(OutletCityErrorState(val["Message"])); } }); } }
2. (可选)优化数据模型,添加批量转换方法
在OutletCityListModel类中添加静态方法,直接将数组转换为模型列表,简化代码:
class OutletCityListModel { int? id; String? city; List<OutletList>? outletList; OutletCityListModel({this.id, this.city, this.outletList}); OutletCityListModel.fromJson(Map<String, dynamic> json) { id = json['Id']; city = json['City']; if (json['OutletList'] != null) { outletList = <OutletList>[]; json['OutletList'].forEach((v) { outletList!.add(new OutletList.fromJson(v)); }); } } // 新增批量转换方法 static List<OutletCityListModel> fromJsonList(List<dynamic> jsonList) { return jsonList.map((item) => OutletCityListModel.fromJson(item)).toList(); } Map<String, dynamic> toJson() { final Map<String, dynamic> data = new Map<String, dynamic>(); data['Id'] = this.id; data['City'] = this.city; if (this.outletList != null) { data['OutletList'] = this.outletList!.map((v) => v.toJson()).toList(); } return data; } }
使用该方法后,Bloc中的解析代码可简化为:
outletCityListData = OutletCityListModel.fromJsonList(val["ResponsePacket"]);
3. 确认状态类的参数类型
确保OutletCityCodeSentState的构造函数接受List<OutletCityListModel>类型:
class OutletCityCodeSentState extends OutletCityState { final List<OutletCityListModel> cityList; OutletCityCodeSentState(this.cityList); }
API返回格式参考
{ "StatusCode": 200, "Message": null, "ResponsePacket": [ { "Id": 100, "City": "Jaipur", "OutletList": [ { "Id": 106, "Title": "Jagatpura", "Address": "RV34+FXQ, Karolan Ka Barh, Jaipur, Rajasthan 302017, India", "City": "Jaipur", "CityId": 100, "IsTakeAway": true, "IsDelivery": true, "IsCodAvailable": true } ] } ], "Success": true, "Errors": null }
内容的提问来源于stack exchange,提问作者Deepak
相关产品推荐
相关产品推荐

