Automatic City Lookup with Google's Location API

development api google
January 10, 2016

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.

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?