Automatic City Lookup with Google's Location API

development api google
January 10, 2016
by Cris Noble

Have you ever come across a web form which asks for your ZIP code and then pre-fills your city and state in for you? I love these types of seemingly small interactions which can end up saving people time and removing some human error. In this post I will show you how to use Google Maps APIs to take a ZIP code and glean the city and state.

ZIP code lookup

In order to get the city and state based off a ZIP code, we are going to want to use Google's Geocoding API. The request is actually very simple[1] if we know the ZIP code. For example http://maps.googleapis.com/maps/api/geocode/json?address=92101 will, in addition to a lot more information, tell you that 92101 is the postal code for San Diego, California. So how do we utilize that information to pre-populate an address form?

Let's start with the basic HTML form:

<form>
  <label for="zip">Zip:</label>
  <input id="zip" name="zip"/>
  <label for="city">City:</label>
  <input id="state" name="state"/>
  <label for="state">State:</label>
  <input id="state" name="state"/>
</form>

Then we need to use javascript to watch for a change on the ZIP code field, and make a request to Google's API to find out the city and state. Finally, we pre-fill the city and state fields.

//when the user clicks off of the zip field:
$('#zip').blur(function(){
  var zip = $(this).val();
  var city = '';
  var state = '';

  //make a request to the google geocode api
  $.getJSON('http://maps.googleapis.com/maps/api/geocode/json?address='+zip).success(function(response){
    //find the city and state
    var address_components = response.results[0].address_components;
    $.each(address_components, function(index, component){
      var types = component.types;
      $.each(types, function(index, type){
        if(type == 'locality') {
          city = component.long_name;
        }
        if(type == 'administrative_area_level_1') {
          state = component.short_name;
        }
      });
    });

    //pre-fill the city and state
    $('#city').val(city);
    $('#state').val(state);
  });
});

The form will now automatically fill in your city and state fields.

example showing when zipcode is filled in, the city and state are filled in as well

We aren't quite done. What about ZIP codes that encompass multiple cities? These are more common than I would have believed. Take 60047 for example, there are 4 different cities listed in the "postcode_localities" filed. The only thing worse than the form not pre-filling itself, is having it pre-fill itself incorrectly.

We can test for multiple "postcode_localities" and turn the city field into select input. Pre-filling the field with the most populous city means looking for the "locality" which matches the original city value, pulled from the address_components.

//check for multiple cities
var cities = response.results[0].postcode_localities;
if(cities) {
  //turn city into a dropdown if necessary
  var $select = $(document.createElement('select'));
  $.each(cities, function(index, locality){
    var $option = $(document.createElement('option'));
    $option.html(locality);
    $option.attr('value',locality);
    if(city == locality) {
      $option.attr('selected','selected');
    }
    $select.append($option);
  });
  $select.attr('id','city');
  $('#city_wrap').html($select);
} else {
  $('#city').val(city);
}

If you want to see the form and javascript code in action, visit the demo page and take a look at the full example Code on Github. Let me know what you think — is pre-filling your information based on ZIP code a time saver or a time waster? Are there better ways to handle the multiple locality problem?

[1] The official google documentation claims that an API key is required to use the API endpoints; I have found they work fine without a key. If you're going to use these methods in a customer-facing application, I would highly recommend using a key. You can get an API key by following the instructions at the Google Location API documentation page.
Back To All Posts?