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

Flutter中List<dynamic>转List<AddressModel>失败求助

问题分析与解决方案

核心问题

你的AddressModel.fromMap方法存在两个关键错误,导致无法正确解析JSON数据:

  1. 字段名不匹配:JSON返回的字段是下划线命名(place_id、display_name),但你在fromMap里使用了驼峰命名的键(placeId、displayName),导致无法从map中获取对应值,最终生成的AddressModel实例都是默认值(0、0.0、空字符串)。
  2. 类型转换错误: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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 03:04:55