Leaflet – Adding onEachFeature Function to Existing Layer

geojsonjavascriptleaflet

I have a GeoJSON layer that comes from a fetch function in another js module. I call this layer through an await function and therefore, I cannot use L.geojson(data, {onEachFeature: onEachfeature}). I need to add the onEachFeature function after loading the data.

I tried to add it through an empty GeoJSON but it doesn't work since I'm calling my layer's attributes in the onEachFeature function.

Does anyone know the solution?

Code :

// Load the layer

const communes_lyr = await getLayer4('communes');

// Set the style (ideally, a function like this but for onEachFeature would be great!)

communes_lyr.setStyle(com_style)

// Create an empty geojson to add the oneachfeature function

var empty_com = L.geoJSON(false, {
  onEachFeature: function (feature, communes_lyr) {
    communes_lyr.bindPopup(feature.properties.COMMUNE + "<br>" + "<br>"
      + "Pollution lumineuse = " + feature.properties.intensity + "%" + "<br>"
      + "Population = " + feature.properties.POPULATION + " habitants" + "<br>"
      + "Superficie = " + feature.properties.superficie + "kmĀ²")
  }
}).addTo(map);

// Add the empty layer with the function to my layer

communes_lyr.addData(empty_com);

Best Answer

Leverage the eachFeature() method of L.GeoJSON. You might not see an eachFeature() method in the L.GeoJSON documentation at first, since that method is implemented by L.GeoJSON's parent class L.LayerGroup.

Usage is similar than Array.prototype.forEach(): the parameter to the method must be a function (or function reference). And that function will receive a L.Layer as its first parameter, e.g.

var group = L.geoJson(/* stuff */);

group.eachLayer(function (layer) {
    layer.bindPopup('Hello');
});

Note how that's equivalent to:

var group = L.geoJson(/* stuff */);

function attachPopupsToStuff(layer) {
    layer.bindPopup('Hello');
}

group.eachLayer(attachPopupsToStuff);

Note that eachFeature iterates on the existing instances of L.Layer, and not on the original GeoJSON features. As implied in the L.GeoJSON example in the documentation, each L.Layer created through L.GeoJSON has a copy of the feature that originated it, in its feature property, e.g.:

var group = L.geoJson(/* stuff */);

group.eachLayer(function (layer) {
    layer.bindPopup(layer.feature.properties.name);
});