ngFor not updating when @Input updated from google map marker event


I’m trying to build a simple app with angular2, I have the below component:

    selector: 'map-menu',
    templateUrl: './angular-app/components/map-menu.html'
export class MapMenuComponent {
    @Input() selectedMarkers: Array<google.maps.Marker>;
    constructor() {
    //      setInterval(() => {
    //          console.log(this);
    //      }, 1000);

when my map-menu.html is:

<ul class="nav nav-sidebar">
    <li *ngFor="#marker of selectedMarkers #i = index"><a href="#">{{}}</a></li>

and in my app html I have:

<map-menu [selectedMarkers]="selectedMarkers"></map-menu>

and the list is not being updated, BUT when I’m adding the commented setInterval it is working fine. what am I missing there?

I’ve created a plunker with the solution


From the User Input dev guide:

Angular only updates the bindings (and therefore the screen) if we do something in response to asynchronous events such as keystrokes.

I’m guessing you don’t have an asynchronous event when the markers array is updated, hence nothing is causing Angular to run its change detection algorithm.

Update: The issue was not that there wasn’t an asynchronous event, the issue was that the asynchronous event (google.maps.Marker.addListener()) is not known by Angular, hence Zone does not monkey patch it, hence Angular doesn’t run its change detection algorithm when the data changes. The solution is to emit the event inside Zone’s run() function:

marker.addListener('click', () => { => {{data:{name: 'another'}});

This will cause Angular to run its change detection algorithm, notice the change, and update the view.

The reason setInterval() works is because it is monkey patched by Zone.

See DiSol’s plunker for more details.

If you want to learn more about Zone, watch Mi┼íko’s video.

See also NgZone API doc.

Answered By – Mark Rajcok

Answer Checked By – Timothy Miller (AngularFixing Admin)

Leave a Reply

Your email address will not be published.