1

I have a react/redux application that I've added a leaflet map to. The leaflet map is being populated through geoJSON. Is there a way I can call a redux action through a user click on a map feature? I'd really like to be able to run an action when the user clicks on a popup. I'd like to store the id number of the feature that the user clicked, so that I can run the action to fetch data and put it in the store, then open another page which has the details for that feature.

This is what I have in leaflet:

myLayer = L.geoJSON(features, {
    //only points here
    filter: function(feature, layer) {
      return (feature.geometry.type == "Point");
    },
     //make each point a circle
    pointToLayer: function (feature, latlng) {
      return L.circleMarker(latlng, geojsonMarkerOptions);
    },
    onEachFeature: function(feature, layer) {
        //popup contents
        var customPopup = `<div class='popuplink' >  <-----user clicks
          <p>${feature.properties.title}</p></div>`;

        //popup options
        var customOptions =
        {
          width: '72', //about 1 inch
          className: 'custom'
        };

        //create layer
        layer.bindPopup(customPopup, customOptions);

    }


});
myLayer.addTo(map);

I tried to put in a link in the popup that when clicked goes to the page I want. (I use react-router in the app). Like this:

        var customPopup = `<a href='/details/${feature.properties.id} >
          <p>${feature.properties.title}</p></a>`;

But when I do that the whole redux store INIT is called and I lose everything. Can someone explain to me why this is happening? I understand that leaflet and react each maintain their own state. But is there a way to form a bridge between them so I can call actions from the map without losing my store?

1
  • If you wrap your leaflet component and make a store for it?
    – fumihwh
    Commented Jan 25, 2017 at 3:20

1 Answer 1

1

OK. I found a work-around for now. It's not elegant, but it works. If someone can tell me of a better solution I'd love to hear it.

I can't call the page directly from leaflet map itself, because redux reinitializes itself and all is lost. So I have to call redux from something that already ON THE DOM.

I created 2 hidden fields on my react page. One is an input field which will hold the id of the data I want to fetch. The second is a button that actually calls the fetch action creator. When the button is 'clicked' the action creator finds the id# in the input field and calls the action with it. Then the action goes and fetches the data, and then uses the router from there to go to the details page.

On the map itself, I created a popup like so:

onEachFeature: function(feature, layer) {

  var popupId = 'info' + feature.properties.id;

   //create a div element
   var domElem = document.createElement('div');
   domElem.id = popupId;

   //what popup will say
   var newContent = document.createTextNode(feature.properties.title);      

   //add the text node to the newly created div. 
   domElem.appendChild(newContent);

 //create onclick event for popup
 domElem.onclick = function() {

   //this points to input field on react container
   var target = document.getElementById('featureId'); 

   //fill it with the id of the feature
   target.value = feature.properties.id;

   //now 'click' the button which calls redux
   var btn = document.getElementById('goToDetails').click();
   }


 //create layer
 layer.bindPopup(domElem);

Not the answer you're looking for? Browse other questions tagged or ask your own question.