Google Places Autocomplete suggestions with Unit No/Subpremise is not coming in the response array
It seems to me like Google is validating that the address is real (well atleast real when they last updated their places database - I guess with government records). The problem is that subdivisions are happening all the time where new "subpremise" addresses are created, and a look up on these seems to be br0ken more often. It's strange that they allow a "non-valid" address as an autocomplete suggestion but then limit the result.
A look up on the Sydney address below will return "subpremise" and "street_number"
"9/321 Pitt Street, Sydney, New South Wales, Australia"
Where the Melbourne address below only gets as accurate as "route"
"2/321 Pitt Street, Brunswick, Victoria, Australia"
The biggest problem is that the result doesn't return the unit or street number anywhere in the reply.
I have hacked together the following JS to compare the user-entered address with the returned result. If the "numbers" are missing, they are added. You can customise as you need to fit with your code.
if (addressType == 'route') {
var regex = RegExp('^(.*)'+GPLACESSTREET.split(' ',1)[0]), // get all the user entered values before a match with the first word from the Google result
result = regex.exec(INPUTFEILD.value);
if ( Array.isArray(result) ) {
FULLSTREETADDRESS = result[1]+''+GPLACESSTREET; // add the street name to the user-entered unit & street number
}
}
The Places Autocomplete API is not designed to support 'subpremise' results. This was reported and answered some time ago in the public issue tracker at https://issuetracker.google.com/35830389
Australian addresses for subpremise results look "close enough" to those of street_address/premise results (they start with mostly digits). This is currently resulting in Place Autocomplete returning what may look like a subpremise result, however note that the type is still "route":
http://maps.googleapis.com/maps/api/place/autocomplete/json?input=9/321%20Pitt%20Street,%20Sydney
description: "9/321 Pitt Street, Sydney NSW, Australia",
place_id: "Eig5LzMyMSBQaXR0IFN0cmVldCwgU3lkbmV5IE5TVywgQXVzdHJhbGlh",
types: ["route","geocode",],
Place Details (and Geocoding) requests with this place_id will in fact find the correct subpremise result:
https://maps.googleapis.com/maps/api/place/details/json?placeid=Eig5LzMyMSBQaXR0IFN0cmVldCwgU3lkbmV5IE5TVywgQXVzdHJhbGlh
"result" : {
"address_components" : [
{
"long_name" : "9",
"short_name" : "9",
"types" : [ "subpremise" ]
},
{
"long_name" : "321",
"short_name" : "321",
"types" : [ "street_number" ]
},
...
"formatted_address" : "9/321 Pitt St, Sydney NSW 2000, Australia",
"types" : [ "subpremise" ],
However, this is not guaranteed to work for all subpremise queries, or even for this particular one in the long term.
A more reliable approach would be to use the Geocoding API to search for the prediction's "description":
https://maps.googleapis.com/maps/api/geocode/json?&address=9%2F321%20Pitt%20St%2C%20Sydney%20NSW%202000%2C%20Australia
"results" : [
{
"address_components" : [
{
"long_name" : "9",
"short_name" : "9",
"types" : [ "subpremise" ]
},
{
"long_name" : "321",
"short_name" : "321",
"types" : [ "street_number" ]
},
...
],
"formatted_address" : "9/321 Pitt St, Sydney NSW 2000, Australia",
"place_id" : "Eik5LzMyMSBQaXR0IFN0LCBTeWRuZXkgTlNXIDIwMDAsIEF1c3RyYWxpYSIdGhsKFgoUChIJkyPU0z2uEmsR-pmiK6UvZUASATk",
"types" : [ "subpremise" ]
Google doesn't support it, but you cant stop customers doing it!
Here is a complete function inspired by @MountainAsh's & @Randell's code:
/* Add the unit number (+ fix the street number) if required.
*
* Idea from https://stackoverflow.com/questions/17936689/google-places-autocomplete-suggestions-with-unit-no-subpremise-is-not-coming-in
*
* Test cases:
* 9/321 Pitt Street, Sydney, New South Wales, Australia <-- Google throws away the unit number
* 2/321 Pitt Street, Brunswick, Victoria, Australia <-- Google says street number = 2
* 1b/123 Clayton Road, Clayton, Victoria, Australia <-- Google says street number = 1
*/
function autofillUnitNumber(txtAutocomplete, txtUnitNumber, txtStreetNumber, txtStreetName) {
var regex = RegExp("^(.*?)\/(.*?) " + txtStreetName.value); // get all the user entered values before a match with the street name; group #1 = unit number, group #2 = street number
var results = regex.exec(txtAutocomplete.value);
if (Array.isArray(results)) { // it was in unit number/street number format
var unitNumber = results[1]; // group #1
var streetNumber = results[2]; // group #2
txtUnitNumber.value = unitNumber;
txtStreetNumber.value = streetNumber;
}
}
Just call it after you have used Google autocomplete to autofill your other form fields eg:
autofillUnitNumber(
document.getElementById("txtAutocomplete"),
document.getElementById("txtUnitNumber"),
document.getElementById("txtStreetNumber"),
document.getElementById("txtStreetName"));