Flutter解析Accommodation模型返回空数组问题求助
API解析返回空数组问题排查
问题概述
在GetX Controller中调用GET API,网络请求正常(返回200状态码),但解析Accommodation模型后得到空数组,预期应填充对应数据。
API调用代码
accommodationUpdateOrCreationDecision() async { List<Accommodation> accommdationModelsList = []; try { var headers = { "Authorization": "..u3nHlV7nZ5-BlGfoBb91of_RZ4W-Qn_tJOUwremWUA", }; acTitleController.value.text = "hello world"; var response = await _apiServices.getReq( endPoint: '${StringConstants.apiBaseUrl}/host/accommodation', headers: headers, ); if (response.statusCode == 400) { log("Error Code ==> ${response.statusCode}"); } log("Status Code ==> ${response.statusCode}"); var accommDataModel = ApiResponseModel.fromJson( response.data, ); if (accommDataModel.success == true) { accommadateUpdateDeleteBool.value = true; for (var data in response.data["data"]["accommodations"]) { Accommodation model = Accommodation.fromJson(data); accommdationModelsList.add(model); } log("response Model : ${accommdationModelsList}"); } else { accommadateUpdateDeleteBool.value = false; } log("response Model success: ${accommDataModel.success.toString()}"); } catch (e) { log("error : ${e.toString()}"); } }
终端输出
[log] Status Code ==> 200 [log] response Model : [] [log] response Model success: true
核心问题代码段
for (var data in response.data["data"]["accommodations"]) { Accommodation model = Accommodation.fromJson(data); accommdationModelsList.add(model); }
预期API响应
{ "success": true, "data": { "message": "Accommodation fetched successfully", "baseUrl": "http://64.226.125.111/rev-be/uploads/", "accommodations": [ { "location": { "type": "Point", "coordinates": [ 67, 24 ] }, "status": "Available", "_id": "64fc661abdd6042a77392b85", "host": "64e762462bbed117abce4cac", "title": "Updated Riverside Retreat", "desc": "Relax by the river at our tranquil retreat.", "images": [ "1695389483120-card-img-logo.png" ], "roomPrice": 2999, "dinnerPrice": 699, "roomCapacity": 12, "dinnerCapacity": 9, "services": [], "isActive": true, "createdAt": "2023-09-09T12:33:30.047Z", "updatedAt": "2023-09-22T13:31:23.121Z", "__v": 0, "reviewsId": [ "6501bc9189fcd2743e9d0e28", "6501bca689fcd2743e9d0e2f" ], "rating": 3.7 } ] } }
解析模型代码
class Accommodation { final String? id; final String? host; final String? title; final String? desc; final List<String>? images; final int? roomPrice; final int? dinnerPrice; final Location? location; final int? roomCapacity; final int? dinnerCapacity; final List<dynamic>? services; final bool? isActive; final DateTime? createdAt; final DateTime? updatedAt; final int? v; final List<dynamic>? bookings; Accommodation({ this.id, this.host, this.title, this.desc, this.images, this.roomPrice, this.dinnerPrice, this.location, this.roomCapacity, this.dinnerCapacity, this.services, this.isActive, this.createdAt, this.updatedAt, this.v, this.bookings, }); factory Accommodation.fromJson(Map<String, dynamic> json) => Accommodation( id: json["_id"], host: json["host"], title: json["title"], desc: json["desc"], images: List<String>.from(json["images"].map((x) => "${StringConstants.imageBaseUrl}$x")), roomPrice: json["roomPrice"], dinnerPrice: json["dinnerPrice"], location: Location.fromJson(json["location"]), roomCapacity: json["roomCapacity"], dinnerCapacity: json["dinnerCapacity"], services: List<dynamic>.from(json["services"].map((x) => x)), isActive: json["isActive"], createdAt: DateTime.parse(json["createdAt"]), updatedAt: DateTime.parse(json["updatedAt"]), v: json["__v"], bookings: json["bookings"] == null ? [] : List<dynamic>.from(json["bookings"]!.map((x) => x)), ); Map<String, dynamic> toJson() => { "_id": id, "host": host, "title": title, "desc": desc, "images": List<dynamic>.from(images!.map((x) => x)), "roomPrice": roomPrice, "dinnerPrice": dinnerPrice, "location": location!.toJson(), "roomCapacity": roomCapacity, "dinnerCapacity": dinnerCapacity, "services": List<dynamic>.from(services!.map((x) => x)), "isActive": isActive, "createdAt": createdAt!.toIso8601String(), "updatedAt": updatedAt!.toIso8601String(), "__v": v, "bookings": bookings == null ? [] : List<dynamic>.from(bookings!.map((x) => x)), }; } class Location { final String? type; final List<double>? coordinates; Location({ this.type, this.coordinates, }); factory Location.fromJson(Map<String, dynamic> json) => Location( type: json["type"], coordinates: List<double>.from(json["coordinates"].map((x) => x?.toDouble())), ); Map<String, dynamic> toJson() => { "type": type, "coordinates": List<dynamic>.from(coordinates!.map((x) => x)), }; }
排查与解决步骤
验证响应数据结构
在循环前添加日志,打印response.data["data"]的完整内容,确认accommodations字段是否存在、字段名拼写是否正确:log("完整数据对象: ${response.data["data"]}");捕获解析异常
当前try-catch未覆盖循环内的模型解析逻辑,若Accommodation.fromJson抛出异常会直接终止循环且无日志。修改代码添加局部捕获:for (var data in response.data["data"]["accommodations"]) { try { Accommodation model = Accommodation.fromJson(data); accommdationModelsList.add(model); } catch (parseError) { log("单条数据解析错误: ${parseError.toString()}"); } }从预期JSON看,模型未包含
status、reviewsId、rating字段,但这些为非必填项不会导致解析失败;需注意Location中整数转double的逻辑是否正常,以及images拼接的StringConstants.imageBaseUrl是否有效。统一数据来源
既然已解析ApiResponseModel,直接从该模型获取数据,避免重复访问原始响应可能出现的不一致:// 需根据ApiResponseModel的实际结构调整data字段的访问方式 for (var data in accommDataModel.data["accommodations"]) { Accommodation model = Accommodation.fromJson(data); accommdationModelsList.add(model); }检查ApiResponseModel的实现
确认ApiResponseModel.fromJson未修改原始response.data,若模型对数据做了转换或过滤,会导致后续访问原始数据出现偏差。
内容的提问来源于stack exchange,提问作者Ali Jawad
相关产品推荐
相关产品推荐

