Flutter中List<dynamic>转List<AddressModel>失败求助
问题分析与解决方案
核心问题
你的AddressModel.fromMap方法存在两个关键错误,导致无法正确解析JSON数据:
- 字段名不匹配:JSON返回的字段是下划线命名(
place_id、display_name),但你在fromMap里使用了驼峰命名的键(placeId、displayName),导致无法从map中获取对应值,最终生成的AddressModel实例都是默认值(0、0.0、空字符串)。 - 类型转换错误:JSON中的
lat和lon是字符串类型(比如"6.6234343"),直接调用toDouble()会抛出异常(String类没有toDouble方法),但因为你用了?.运算符,异常被静默处理,最终得到默认值0.0。
修正后的AddressModel类
class AddressModel { int placeId; double lat; double lon; String displayName; AddressModel({ required this.placeId, required this.lat, required this.lon, required this.displayName, }); factory AddressModel.fromMap(Map<String, dynamic> map) { return AddressModel( // 修正字段名,对应JSON中的place_id placeId: (map['place_id'] ?? 0).toInt(), // 先将字符串转为double,处理空值情况 lat: double.tryParse(map['lat'] ?? '0.0') ?? 0.0, lon: double.tryParse(map['lon'] ?? '0.0') ?? 0.0, // 修正字段名,对应JSON中的display_name displayName: map['display_name'] ?? '', ); } AddressModel copyWith({ int? placeId, double? lat, double? lon, String? displayName, }) { return AddressModel( placeId: placeId ?? this.placeId, lat: lat ?? this.lat, lon: lon ?? this.lon, displayName: displayName ?? this.displayName, ); } Map<String, dynamic> toMap() { final result = <String, dynamic>{}; result.addAll({'placeId': placeId}); result.addAll({'lat': lat}); result.addAll({'lon': lon}); result.addAll({'displayName': displayName}); return result; } String toJson() => json.encode(toMap()); factory AddressModel.fromJson(String source) => AddressModel.fromMap(json.decode(source)); @override String toString() { return 'AddressModel(placeId: $placeId, lat: $lat, lon: $lon, displayName: $displayName)'; } @override bool operator ==(Object other) { if (identical(this, other)) return true; return other is AddressModel && other.placeId == placeId && other.lat == lat && other.lon == lon && other.displayName == displayName; } @override int get hashCode { return placeId.hashCode ^ lat.hashCode ^ lon.hashCode ^ displayName.hashCode; } }
额外建议
在转换列表时,可以加入异常捕获,避免单个数据解析失败导致整个列表为空:
final List addressList = json.decode(response.body); List<AddressModel> addresses = []; for (var e in addressList) { try { addresses.add(AddressModel.fromMap(e)); } catch (e) { print('解析地址失败: $e'); // 可以选择跳过错误数据或做其他处理 } }
这样修改后,你再打印addresses就能看到正确解析后的实例了。
内容的提问来源于stack exchange,提问作者Zenixo
相关产品推荐
相关产品推荐

