Olivier Pons
Olivier Pons

Reputation: 15778

Google Maps API: how to check if an address or location is valid?

Here's my problem: I have a web page where I'm trying to use autocomplete, like that, very very basic:

<script type="text/javascript"
        src="https://maps.googleapis.com/maps/api/js?libraries=places"></script>
<script type="text/javascript">
    $(document).ready(function () {
        new google.maps.places.Autocomplete(
            document.getElementById('testtest'), {}
        );
</script>

When the user posts the form, on the server side, I will get a text value like

"Pentagone, North Rotary Road, Arlington, Virginie, États-Unis"

and so. So, on the server side, is there a way to validate that this address is good ie ask google?

Upvotes: 13

Views: 34231

Answers (2)

tsnewnami
tsnewnami

Reputation: 11

Angular 12

I still haven't found a valid solution to this from Google. This is what I did:

I have a field variable within my component:

validRegion: boolean = false;

Whenever the event handler from Google Maps Places Autocomplete fires (only fires if a valid location is found), I toggle the field variable to true.

  private getPlaceAutocomplete() {
    const autocomplete = new google.maps.places.Autocomplete(this.addresstext.nativeElement,
        {
            componentRestrictions: { country: 'AUS' },
            types: [this.adressType]  // 'establishment' / 'address' / 'geocode'
        });
    google.maps.event.addListener(autocomplete, 'place_changed', () => {
        const place = autocomplete.getPlace();
        console.log(place.geometry.location.lat());
        console.log(place.geometry.location.lng());
        this.validRegion = true; # TOGGLE HERE
        console.log(this.validRegion);
    });
  }

To ensure that the user can not change the location to an invalid location after a valid one has been found - I set a keystroke event (keydown) on the input to set the validRegion variable back to false. This will only become true once the event handler fires again

 <input
      matInput
      required
      class="input"
      type="text"
      [(ngModel)]="autocompleteInput"
      #addresstext
      (keyup)="validationRegion()"
 >
  validationRegion(){
    this.validRegion = false;
  }

Upvotes: 1

I wrestled a bear once.
I wrestled a bear once.

Reputation: 23379

I don't know why it has to be on the server side. You should be doing that with Google as soon as they enter it. Don't make them submit the form and have to do it all over again because you want to do validation on the server side.

HTML

<input type="text" id="address" onchange="doGeocode()" />

<!-- require Google Maps API -->
<script src="//maps.googleapis.com/maps/api/js"></script>

JS

function doGeocode() {
   var addr = document.getElementById("address");
   // Get geocoder instance
   var geocoder = new google.maps.Geocoder();
    
   // Geocode the address
   geocoder.geocode({
       'address': addr.value
   }, function(results, status) {
       if (status === google.maps.GeocoderStatus.OK && results.length > 0) {
    
           // set it to the correct, formatted address if it's valid
           addr.value = results[0].formatted_address;;
       } else {

          // show an error if it's not
          alert("Invalid address");
       }
   });
};

However, if you want to use PHP you can try this...

function geocode($address) {
    $return = array();
    $address = urlencode($address);
    $key = "put your key here,,,";
    $url = "https://maps.google.com/maps/api/geocode/json?key=$key&address={$address}";
    $resp_json = file_get_contents($url);
    $resp = json_decode($resp_json, true);

    if ($resp['status']!=='OK') return false;

    foreach($resp['results'] as $res) {
        $loc = array(
            "zipcode"=>null,
            "formatted"=>null
        );

        foreach ($res['address_components'] as $comp) {
            if (in_array("postal_code", $comp['types'])) 
                $loc['zipcode'] = $comp['short_name'];
        }

        $loc['formatted'] = $res['formatted_address'];
        $loc['lng'] = $res['geometry']['location']['lng'];
        $loc['lat'] = $res['geometry']['location']['lat'];
        $return[] = $loc;
    }

    return $return;
}

Upvotes: 18

Related Questions