PaulJ
PaulJ

Reputation: 1717

How do I use the new Google Places API's autocomplete?

I am mantaining a website with a distance calculator, that has 2 text fields that use Google's Autocomplete to select two locations. I am trying to migrate it to the new Place API and to make it use sessions for the autocomplete feature.

Now, from what I have been told, if you use Google's JS widget, it should be using the new Places API automatically, but in my case it's not happening. My HTML is:

                <input type="text" id="punto_inicio" name="origen" value="" onFocus="geolocate()"  class="formc full-width input-text" data-live-search="true" data-toggle="tooltip" data-placement="top" required>

                <input type="text" id="punto_final" name="destino" value="" class="formc full-width input-text" data-live-search="true" data-toggle="tooltip" data-placement="top"  required>

<script src="https://maps.googleapis.com/maps/api/js?key={{ googlemapsAPIkey }}&libraries=places&callback=initAutocomplete&language=es-ES&v=weekly" async defer></script>

(I added the "v=weekly" part to try to force Google to load the newest version of the widget, but initially I didn't use it. Neither works).

My JS code is:

function initAutocomplete() {       
    var sessionTokenInicio = new google.maps.places.AutocompleteSessionToken();
    var sessionTokenFinal = new google.maps.places.AutocompleteSessionToken();
    
    var autocompleteInput = document.getElementById('punto_inicio');
    autocomplete = new google.maps.places.Autocomplete(autocompleteInput, 
            {
            fields: ["address_components", "geometry", "formatted_address", "name", "url", "website"],
            componentRestrictions: { country: ["es", "fr", "pt"] }
            }
        );
    autocomplete.setOptions({ sessionToken: sessionTokenInicio });

    var autocomplete2Input = document.getElementById('punto_final');
    var options2 = { componentRestrictions: { country: ['es', 'fr', 'pt'] } };
    autocomplete2 = new google.maps.places.Autocomplete(autocomplete2Input, 
            {
            fields: ["address_components", "geometry", "formatted_address", "name", "url", "website"],
            componentRestrictions: { country: ["es", "fr", "pt"] }
            }       
        );
    autocomplete2.setOptions({ sessionToken: sessionTokenFinal });


    autocomplete.addListener('place_changed', function() {
        fillInAddress(autocomplete, "", sessionTokenInicio);
        sessionTokenInicio = new google.maps.places.AutocompleteSessionToken();
        autocomplete.setOptions({ sessionToken: sessionTokenInicio });          
    });

    autocomplete2.addListener('place_changed', function() {
        fillInAddress(autocomplete2, "2"), sessionTokenInicio;
        sessionTokenFinal = new google.maps.places.AutocompleteSessionToken();
        autocomplete2.setOptions({ sessionToken: sessionTokenFinal });
    });         

}

function fillInAddress(autocomplete, unique, sessionToken) {

    var place = autocomplete.getPlace();

    for (var component in componentForm) {
        if (!!document.getElementById(component + unique)) {
            document.getElementById(component + unique).value = '';
        }
    }

   var service = new google.maps.places.PlacesService(document.createElement('div'));
    service.getDetails(
        {
            placeId: place.place_id,
            sessionToken: sessionToken,
            fields: ["address_components", "geometry", "name", "formatted_address"] // Limit fields to reduce cost
        },
        function (placeDetails, status) {
            if (status === google.maps.places.PlacesServiceStatus.OK) {
                // Update fields with place details
                document.getElementById('name' + unique).value = placeDetails.name || "";
                document.getElementById('latlng' + unique).value = placeDetails.geometry?.location || "";
                //document.getElementById('url' + unique).value = placeDetails.url || "";
                //document.getElementById('web' + unique).value = placeDetails.website || "";

                if (placeDetails.address_components) {
                    for (var i = 0; i < placeDetails.address_components.length; i++) {
                        var addressType = placeDetails.address_components[i].types[0];
                        if (componentForm[addressType] && document.getElementById(addressType + unique)) {
                            var val = placeDetails.address_components[i][componentForm[addressType]];
                            document.getElementById(addressType + unique).value = val || "";
                        }
                    }
                }

                if (document.getElementById('latlng' + unique).value !== '') {
                    document.getElementById('ok' + unique).checked = true;
                    document.getElementById('sel' + unique).innerHTML = placeDetails.formatted_address || "";
                }
            } else {
                console.error("Failed to fetch place details:", status);
            }
        }
    );
}


function geolocate() {
    if (navigator.geolocation) {
      navigator.geolocation.getCurrentPosition(function(position) {
        var geolocation = {
          lat: position.coords.latitude,
          lng: position.coords.longitude
        };
        var circle = new google.maps.Circle({
          center: geolocation,
          radius: position.coords.accuracy
        });
      });
    }
}

Despite all of the above, when I load the page I see it still using the old Places API endpoint:

https://maps.googleapis.com/maps/api/place/js/AutocompletionService.GetPredictions

To make sure, I created a new API key and restricted so that it only used the new Places API... and now the page doesn't load and says: "Google Maps JavaScript API error: ApiTargetBlockedMapError". So it looks like it's trying to use the old Places API no matter what I do.

What's wrong?

Upvotes: 0

Views: 80

Answers (0)

Related Questions