1

I use Leaflet for drawing a map and try to use Angular Material for displaying some modals but I encountered an issue.

The modal (ModalComponent) should be opened when the user clicks on the map, for which I've added a click event (see the MapComponent). Inside this event, I am calling a method, this.modalService.openModal, which will open the modal.

The issue is that the modal is opening empty. If I press ok/cancel, which should close the modal, this is rendered again but with proper data. The second time when I press on a button, the modal will be closed.

Strange behavior that I observed, is that the modal goes through the constructor but not through the ngOnInit method. Only after I click on a button it goes through ngOnInit.

Here you can find the sample code: https://stackblitz.com/edit/angular-ivy-ptqcvv?file=src%2Fapp%2Fmap%2Fmap.component.html

Here is my config:

  • npm 6.13.4
  • Angular CLI 8.3.29
  • Angular 8.2.14
  • Angular Material 8.2.3
  • Google Chrome 84

Does someone have an idea of what is happening?

Doro
  • 335
  • 2
  • 6
  • 24

1 Answers1

4

onMapReady callback is executed outside of Angular zone which leads to no Angular change detection executed.

You should bring that execution back to Angular zone in order change detection to work properly.

import { NgZone } from '@angular/core';

export class MapComponent  {
  constructor(private zone: NgZone, ...) {}

  onMapReady(map: Map) {
    this.map = map;
    console.log('map ready'); 

    this.map.addEventListener('click', () => {
      console.log('clicked')
      this.zone.run(() => this.modalService.openModal())
    })
  }
}

Forked Stackblitz

yurzui
  • 205,937
  • 32
  • 433
  • 399
  • Thanks for help! Is this because of the way Leaflet adds the click event? – Doro Aug 26 '20 at 06:28
  • Thanks! for my case there's no Map event, it is just a normal angular component (inside a route, not at app.component.ts) popping out mat-dialog. I guessed mat-dialog's load mechanism runs outside Angular's zone? – mithocondria Jun 15 '22 at 08:43
  • Great answer! I had the same issue when trying to launch MatDialog from a global error handler: provider:[{provide: ErrorHandler, useClass: xxx}] – Roy Milder Aug 28 '22 at 08:39