google-mapsflutterdartfrontendgeocoding

How to extract city locality and country from Geocoder response in Flutter


I already have a response from the geocoder with the whole readable address. I want a good way to retrieve the city and country from this address

I tried this method but it didnt work

print(json.decode(response.body)['results'][0].getLocality());//didnt work

here is my code:


  final url = 'https://maps.googleapis.com/maps/api/geocode/json?latlng=$lat,$lng&key=$GOOGLE_API_KEY';
  final response = await http.get(url);
  print(response.body);
  print(json.decode(response.body)['results'][0].getLocality());//didnt work
  return  json.decode(response.body)['results'][0]['formatted_address'];

}```

Solution

  • The problem is that in this case json.decode(response.body) can just be used like a Map, so you can't call a method that doesn't have, like getLocality().

    To be able to do that, you should parse the JSON into an object that has that method. I recommend you this article to learn more about parsing JSON: Parsing complex JSON in Flutter


    If you want to access the country and locality without parsing the JSON, you could do something like this:

    String body = '{"results":[{"address_components":[{"long_name":"1600","short_name":"1600","types":["street_number"]},{"long_name":"Amphitheatre Pkwy","short_name":"Amphitheatre Pkwy","types":["route"]},{"long_name":"Mountain View","short_name":"Mountain View","types":["locality","political"]},{"long_name":"Santa Clara County","short_name":"Santa Clara County","types":["administrative_area_level_2","political"]},{"long_name":"California","short_name":"CA","types":["administrative_area_level_1","political"]},{"long_name":"United States","short_name":"US","types":["country","political"]},{"long_name":"94043","short_name":"94043","types":["postal_code"]}],"formatted_address":"1600 Amphitheatre Parkway, Mountain View, CA 94043, USA","geometry":{"location":{"lat":37.4224764,"lng":-122.0842499},"location_type":"ROOFTOP","viewport":{"northeast":{"lat":37.4238253802915,"lng":-122.0829009197085},"southwest":{"lat":37.4211274197085,"lng":-122.0855988802915}}},"place_id":"ChIJ2eUgeAK6j4ARbn5u_wAGqWA","types":["street_address"]}],"status":"OK"}';
    List<dynamic> addressComponents =
        json.decode(body)['results'][0]['address_components'];
    String country = addressComponents
        .firstWhere((entry) => entry['types'].contains('country'))['long_name'];
    String locality = addressComponents.firstWhere(
        (entry) => entry['types'].contains('locality'))['long_name'];
    print('country: $country');
    print('locality: $locality');
    

    In case there can be more than one country or locality, you could do this:

    List<dynamic> countries = addressComponents
        .where((entry) => entry['types'].contains('country'))
        .toList()
        .map((entry) => entry['long_name'])
        .toList();
    List<dynamic> localities = addressComponents
        .where((entry) => entry['types'].contains('locality'))
        .toList()
        .map((entry) => entry['long_name'])
        .toList();
    print('countries: $countries');
    print('localities: $localities');