I've set up my application using angular5 with ngx-leaflet (https://github.com/Asymmetrik/ngx-leaflet).
I start with a blank map. When a user clicks a button, markers appear on the map. When a user selects a marker, that marker is identified to a country and that country is linked with other countries based on some other (non-important) data.
<div id="map-sidebar">
<div class="map-buttons-bar">
<button class="btn btn-primary" (click)="addLayer()">Set Marker</button>
</div>
</div>
In my .ts file, I have
addLayer(){
var n_marker = marker([38.9072, -77.0369], {icon: this.anomalyIcon});
n_marker.on('click', (e)=>{
this.mapToPartnerCountries();
})
this.lLayers.push(n_marker);
}
mapToPartnerCountries(){
var n_marker = marker([39.9072, -78.0369], {icon: this.anomalyIcon});
this.lLayers.push(n_marker);
//var newLayer = geoJSON(geo as any);
//this.lLayers.push(newLayer);
}
My issue is the new layer does not appear when the mapToPartnerCountries() method is run. But if I click the button again, it appears. GeoJson does the same thing as well. Am I doing this the correct way?
Also the this.lLayers field is used in the map element...
<div class="map-container"
leaflet
[leafletOptions]="mapOptions"
[leafletLayersControl]="layersControl"
[leafletLayers]="lLayers"
>
Angular uses zones to determine what events do and do not trigger change detection. Any event that is propagated from a template (e.g., the (click) event) will trigger change detection unless you specifically configure it not to. That is why when you click again, the changes are applied.
Leaflet events are intentionally set up to happen outside of the Angular zone (for various reasons, but mostly performance related). You can read more here. Angular won't detect any changes made to component properties if the changes are made outside of the Angular zone.
You are modifying this.lLayers
inside of a callback on a Marker click event, which is likely occurring outside of Angular's zone. To get Angular to "see" this modification, you will need to perform it inside of Angular's zone using NgZone.run()
.
For example:
constructor(private zone: NgZone) {}
addLayer(){
var n_marker = marker([38.9072, -77.0369], {icon: this.anomalyIcon});
n_marker.on('click', (e) => {
this.zone.run(() => {
this.mapToPartnerCountries();
});
})
this.lLayers.push(n_marker);
}
That code will ensure that this.mapToPartnerCountries();
is run inside of Angular's zone so that change detection will be performed.