Reputation: 1671
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
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®ion=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®ion=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
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