Esri Maps PopupTemplate's content method called only once per feature

532 Views Asked by At

I am using Esri maps inside an Angular app, and I am rendering my popups as Angular components with data published from the PopupTemplate's content method:

layer.popupTemplate = new PopupTemplate({
  content: (feature: { graphic: __esri.Graphic }) => {
    this.publishPopupData(layer, feature.graphic.attributes);
    return popupComponent.viewContainerRef.element.nativeElement;
  },
  // other properties... 
});

This works well, except in the case where there are multiple features at a given point. When the user cycles through the features, if he/she returns to a feature that was already displayed, the content method does not execute, so the popup data is not published.

I can access the currently selected feature on the MapView's popup, but I need to know what layer the feature came from in order to publish the data properly (each layer has unique requirements for processing the ArcGIS data into the models used by the popups).

mapView.popup.watch('selectedFeature', (graphic: __esri.Graphic) => {
  const layer = ???;
  this.publishPopupData(layer, graphic.attributes);
});

Nominally, graphic.layer should contain the layer reference, but in my case it is always null.

Is there a way to force the popups to always call the content method, even if it was already executed for a given feature? Alternatively, is there a way to get the layer a feature belongs to from MapView.popup (or something else I have not considered)?

If it matters, the popups are for MapImageLayer sublayers.

1

There are 1 best solutions below

0
On

It's normal that the content function is not called again when you return to a feature popup that was already displayed. I think the problem lays in the fact that you are overwritting the popupComponent variable each time the content function is called. Instead, this.publishPopupData() should return something that you will add into a new html element.

I will provide a javascript answer because I don't know typescript very well:

layer.popupTemplate = new PopupTemplate({
  content: function(graphic) {
    var popupElement = document.createElement("div");
    //use popupElement.innerHTML if this.publishPopupData() returns a string or use popupElement.appendChild() if it's an html element
    popupElement.innerHTML = this.publishPopupData(layer, graphic.attributes); 
    return popupElement;
  },
  // other properties... 
});