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

Flutter调用Google Nearby Search API生成Marker遇类型转换错误

解决Flutter中Google Nearby Search API JSON转换类型不匹配问题

问题核心

你碰到的type '_Map<String, dynamic>' is not a subtype of type 'String'错误,本质是JSON解析时把嵌套的Map类型数据错误赋值给了String类型变量,大概率出在解析地点经纬度(geometry.location)这类嵌套字段的环节。

分步排查与解决

1. 先明确API返回的JSON结构

先确认Google Nearby Search API返回的核心结构(以标准响应为例):

{
  "results": [
    {
      "geometry": {
        "location": {
          "lat": 37.7749,
          "lng": -122.4194
        }
      },
      "name": "Sample Place",
      "vicinity": "Sample Address"
    }
  ]
}

注意geometry.location是嵌套的Map对象,不是字符串。

2. 定义正确的数据模型类

没有匹配的模型类,直接解析JSON很容易踩类型坑,先写对应模型:

class NearbyPlace {
  final double lat;
  final double lng;
  final String name;
  final String vicinity;

  NearbyPlace({
    required this.lat,
    required this.lng,
    required this.name,
    required this.vicinity,
  });

  // 从JSON解析的工厂方法
  factory NearbyPlace.fromJson(Map<String, dynamic> json) {
    return NearbyPlace(
      lat: json['geometry']['location']['lat'] as double,
      lng: json['geometry']['location']['lng'] as double,
      name: json['name'] as String,
      vicinity: json['vicinity'] as String,
    );
  }
}

⚠️ 重点:别尝试把json['geometry']或json['geometry']['location']直接赋值给String变量,必须深入到lat和lng字段提取数值。

3. 修正HttpRepository的解析逻辑

检查你的HttpRepository实现,确保解析响应时正确处理嵌套字段:

// 假设你的HttpRepository中有这样的请求方法
Future<List<NearbyPlace>> fetchNearbyPlaces(String url) async {
  final response = await http.get(Uri.parse(url));
  
  if (response.statusCode == 200) {
    final Map<String, dynamic> data = json.decode(response.body);
    final List<dynamic> results = data['results'];
    
    // 转换为NearbyPlace列表
    return results.map((placeJson) => NearbyPlace.fromJson(placeJson)).toList();
  } else {
    throw Exception('加载周边地点失败');
  }
}

如果之前代码里错误把某个Map字段(比如geometry)赋值给String,这里必须修正。

4. 调整NearbyMosquesController的Marker创建逻辑

在GetX控制器中,确保从NearbyPlace实例提取经纬度生成Marker:

class NearbyMosquesController extends GetxController {
  final RxList<Marker> markers = <Marker>[].obs;
  final HttpRepository httpRepo;

  NearbyMosquesController({required this.httpRepo});

  Future<void> loadNearbyMosques() async {
    try {
      final places = await httpRepo.fetchNearbyPlaces(YOUR_API_URL);
      
      markers.clear();
      for (var place in places) {
        markers.add(
          Marker(
            markerId: MarkerId(place.name),
            position: LatLng(place.lat, place.lng),
            infoWindow: InfoWindow(
              title: place.name,
              snippet: place.vicinity,
            ),
          ),
        );
      }
    } catch (e) {
      print('生成Marker出错: $e');
    }
  }
}

⚠️ 别直接从原始JSON里提取location时把Map当成String用,必须通过模型类解析后再拿数值。

5. 常见错误排查点

  • 检查是否写过类似String location = json['geometry']['location'];的代码,这是典型错误,因为location是Map不是String。
  • 确保所有JSON字段类型匹配:比如lat/lng是double类型,别用int接收;name/vicinity是String类型,别用Map接收。
  • 如果用自动生成的模型类(比如json_serializable),检查注解是否正确,嵌套字段是否被正确解析。

快速验证方法

解析JSON时加打印语句,确认字段类型:

print(json['geometry']['location'].runtimeType); // 应该输出 _Map<String, dynamic>
print(json['geometry']['location']['lat'].runtimeType); // 应该输出 double

这样能快速定位哪个字段的类型处理出错。

内容的提问来源于stack exchange,提问作者haker man

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 17:06:25