Stetzon
Stetzon

Reputation: 739

Trouble binding events/popups to existing leaflet geojson layer

I am trying to add local json data to a GeoJson layer in Leaflet, and then (for now) bind a popup to each feature in the json. The trouble is that I am unable to first create a geojson layer, and then later bind popups. Is there any way to do this? I am only able to create the layer and add the popups at the same time. What I have so far:

Create the map.

map = new L.Map('map');

Grab the local json file:

{
"type": "FeatureCollection",
"features": [
    {
        "type": "Feature",
        "properties": {
            "name": "Denver",
            "amenity": "Baseball Stadium",
            "popupContent": "This is where the Rockies play!"
        },
        "geometry": {
            "type": "Point",
            "coordinates": [-102.99404, 37.75621]
        }
    },
    {
        "type": "Feature",
        "properties": {
            "name": "Baltimore",
            "amenity": "Baseball Stadium",
            "popupContent": "This is where the Orioles play!"
        },
        "geometry": {
            "type": "Point",
            "coordinates": [-76.6167, 39.2833]
        }
    }
    ]
}

and send json through to plotData():

function plotData( data ) 
{
  var pointLayer = L.geoJson().addTo(map);

  // 1. works
  L.geoJson(data, {
    onEachFeature: onEachFeature
  }).addTo(map);


  // 2. does not bind popups
  pointLayer.addData( data, {
    onEachFeature: onEachFeature
      }
  );

  // 3. Error - invalid GeoJson Object
  pointLayer.addData( L.geoJson(data, {
    onEachFeature: onEachFeature
      })
  );
}

function onEachFeature( feature, layer ) 
{
  layer.bindPopup( feature.properties.name );
}

The markers display just fine on the map for scenario 1 and 2 (with 1 also displaying popups). Now, is there any reason why I should not be trying to first create the layer and then bind actions to the features? Is it better practice to just do what I have stated in 1?

Upvotes: 3

Views: 1196

Answers (1)

Ilja Zverev
Ilja Zverev

Reputation: 953

The third option won't work, because you're feeding L.Layer object where a GeoJSON object should go. L.GeoJSON.addData() function does not have onEachFeature parameter. Basically, when you have processed a GeoJSON, its feature properties are gone.

There are two ways to proceed.

// create empty GeoJSON layer
var pointLayer = L.geoJson(null, { onEachFeature: storeName }).addTo(map);
// add data to it later, invoking storeName() function
pointLayer.addData(data);
// which stores names
function storeName(f, l) { l._gname = f.properties.name; }
// and when you're ready...
pointLayer.eachLayer(addPopupFromGName);
// add popups with stored name
function addPopupFromGName(l) { l.bindPopup(l._gname); }

Or just add onEachFeature function to L.GeoJSON layer options:

var pointLayer = L.geoJson(null, { onEachFeature: onEachFeature }).addTo(map);

Upvotes: 1

Related Questions