Search code examples
jquerygoogle-maps-api-3

Get UK outcode (postal code prefix) when performing geolocation request


with the help of SA I have managed to get the lat, lng and the viewport bounds when a user wants to geolocate their current location.

Today, we had a person ask if we can also obtain the outcode ("postal_code_prefix") from the request. The is the first three/four digits of the UK postcode. I said this shouldn't be a problem and I can even see the outcode in the console. I read on this thread, Retrieving Postal Code with Google Maps Javascript API V3 Reverse Geocode, several good and bad answers and the most succinct one was the following:

for (i = 0; i < results.length; i++) {
    for (var j = 0; j < results[i].address_components.length; j++) {
        for (var k = 0; k < results[i].address_components[j].types.length; k++) {
            if (results[i].address_components[j].types[k] == "postal_code_prefix") {
                outcode = results[i].address_components[j].short_name;
            } else if (results[i].address_components[j].types[k] == "postal_code") {
                outcode = results[i].address_components[j].short_name;
            }
        }
    }
}

I've tested this on 3 different computers and its worked perfectly. Can anyone see and drawbacks with this, or improvements? For example it would be ideal to have a one line solution, such as:

var outcode = results[1].address_components.postal_code_prefix.short_name();

I've searched the entire day and found no simple solution.

many thanks.


Solution

  • if (place.address_components) {
        for(var i=0; i < place.address_components.length; i++) {
        var component = place.address_components[i];
        if(component.types[0] == "postal_code_prefix") {
            outcode = component.long_name;
        } else if((component.types[0] == "postal_code") && (component.types[0] != "postal_code_prefix")) {
            zipcode = component.long_name;
            zipcode = zipcode.split(' ');
            outcode = zipcode[0];
            }
        } else {
            outcode = reverse_geocode(lat, lng);
        }
    }
    

    essentially what I've done is told the function to find the postal_code or postal_code_prefix from Places, and if neither have been found then take the latitude and longitude from the place.geometry.location.lat(); and place.geometry.location.lng(); and forward these to a function that reverse geocodes them so as to obtain the outcode. The reverse geocode function is as follows:

    function reverse_geocode(lat, lng) {
        var geocoder = new google.maps.Geocoder();
        var latlng = new google.maps.LatLng(lat,lng);
        geocoder.geocode({'latLng': latlng}, function(results, status) {
        if (status == google.maps.GeocoderStatus.OK) {
          if (results[0]) {
            // this code has been validated by Luke
            for(var i=0; i < results[0].address_components.length; i++) {
                    var component = results[0].address_components[i];
                    if(component.types[0] == "postal_code_prefix") {
                        appendHiddenFormField("outcode", component.long_name);
                        appendHiddenFormField("gz", "1");
                    } else if((component.types[0] == "postal_code") && (component.types[0] != "postal_code_prefix")) {
                        zipcode = component.long_name;
                        zipcode2 = zipcode.split(' ');
                        appendHiddenFormField("outcode", zipcode2[0]);
                        appendHiddenFormField("gz", "1");
                    }
                }
            } else {
                console.log("no results found");
                appendHiddenFormField("outcode", "");
            }
        } else {
            console.log('Geocoder failed due to: ' + status);
            appendHiddenFormField("outcode", "");
        }
      });
    }