Reputation: 3850
I have an Angluar2 app that includes the Google Maps JS API. I load Google Maps like this:
<script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY"> </script>
I listen to events on the map like this:
this.map = new google.maps.Map(document.getElementById('map'), {
center: {lat: lat, lng: lng},
zoom: zoom
});
this.map.addListener('click', () => {
console.log("Map click");
this.key++;
});
I show the key in the template:
<div>{{key}}</div>
Updating the key
, using a regular function takes immediate effect in the UI. Updating the key
using the above function takes 10-20 seconds to update. I can see that the event is immediately triggered in the console. If I switch tabs, for example: My-App -> Another Page -> back to My-App, the value is updated immediately as well.
Therefore, I figured that the UI changes are not detected and updated my above code to:
constructor(private ref: ChangeDetectorRef) {
.... code in between ....
this.map.addListener('click', () => {
console.log("Map click");
this.key++;
this.ref.detectChanges();
});
This updates the key
immediately.
Why are events from Google Maps not recognized immediately as usual?
BTW: This also happens with other Events, for example center_change or Marker click.
Upvotes: 1
Views: 493
Reputation: 21
When using third party JS libraries in Angular2, you will need to make sure the library's events are being fired within Angular's zone (https://medium.com/@MertzAlertz/what-the-hell-is-zone-js-and-why-is-it-in-my-angular-2-6ff28bcf943e#.kumw91vmr).
When using the Google Maps JS API, the events fired from clicks on the map and markers are fired outside of the Angular zone.
There is an Angular2 core module called NgZone that will help you with this. By importing the NgZone module, and then specifying that you want to run the map click events within the zone, you can ensure that Angular2 detects the events immediately:
Within your map component, import NgZone:
import { Component, NgZone } from '@angular/core';
Within the component's constructor, declare NgZone:
constructor(private ref: ChangeDetectorRef, public zone: NgZone) {...}
Within your marker's click event, run your code inside the zone's 'run' method:
let me = this;
this.map.addListener('click', () => {
me.zone.run(() => {
console.log("Map click");
this.key++;
this.ref.detectChanges();
});
});
Upvotes: 2