C. Kearns
C. Kearns

Reputation: 1671

Loading Google Places Autocomplete Async Angular 2

I am trying to instantiate a Google Places Autocomplete input within an Angular 2 component. I use this code to do it:

loadGoogle() {
    let autocomplete = new google.maps.places.Autocomplete((this.ref.nativeElement), { types: ['geocode'] });
    let that = this
    //add event listener to google autocomplete and capture address input
    google.maps.event.addListener(autocomplete, 'place_changed', function() {
      let place = autocomplete.getPlace();
      that.place = place;
      that.placesearch = jQuery('#pac-input').val();
    });
    autocomplete.addListener()
  }

Normally, I believe, I would use the callback function provided by the Google API to ensure that it is loaded before this function runs, but I do not have access to it within a component's scope. I am able to load the autocomplete input 90% of the time, but on slower connections I sometimes error out with

google is not defined

Has anyone figured out how to ensure the Google API is loaded within a component before instantiating.

Upvotes: 3

Views: 4461

Answers (2)

Manish
Manish

Reputation: 2180

I used it the same way as explained above but as per google page speed i was getting this suggestion,

Remove render-blocking JavaScript: http://maps.googleapis.com/…es=geometry,places&region=IN&language=en

So i changed my implementation,

<body>
  <app-root></app-root>
  <script src="http://maps.googleapis.com/maps/api/js?client=xxxxx2&libraries=geometry,places&region=IN&language=en" async></script>
</body>

/* Now in my component.ts */

  triggerGoogleBasedFn(){
    let _this = this;

    let interval = setInterval(() => {
      if(window['google']){
        _this.getPlaces();
        clearInterval(interval);
      }
    },300)
  }

You can do one more thing, emit events once the value(google) is received,& trigger your google task inside them.

Upvotes: 0

Andyccs
Andyccs

Reputation: 535

Not sure whether this will help, but I just use a simple script tag in my index.html to load Google API and I never get any error. I believe you do the same as well. I post my codes here, hope it helps.

Note: I use Webpack to load other scripts, except for Google Map API.

<html>
  <head>
    <base href="/">
    <title>Let's Go Holiday</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <!-- Google Map -->
    <script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?key=<your-key>&libraries=places"></script>
  </head>

  <body>
    <my-app>Loading...</my-app>
  </body>
</html>

And then in your component:

...
declare var google: any;

export class SearchBoxComponent implements OnInit {

  ngOnInit() {
    // Initialize the search box and autocomplete
    let searchBox: any = document.getElementById('search-box');
    let options = {
      types: [
        // return only geocoding results, rather than business results.
        'geocode',
      ],
      componentRestrictions: { country: 'my' }
    };
    var autocomplete = new google.maps.places.Autocomplete(searchBox, options);

    // Add listener to the place changed event
    autocomplete.addListener('place_changed', () => {
      let place = autocomplete.getPlace();
      let lat = place.geometry.location.lat();
      let lng = place.geometry.location.lng();
      let address = place.formatted_address;
      this.placeChanged(lat, lng, address);
    });
  }
  ...
}

Upvotes: 4

Related Questions