0

I have a dropdown menu which allows users to select a certain month. An observable array changes the layers of my leaflet map according to user selection (works perfectly).

Now I need the selection value myMonth (zero based month number) for another function which populates a popup window with content. I just don't find a working solution for using the variable myMonth outside the viewModel function... Any help highly appreciated!

Here's my code which results in: popupcontent = "Selected month: undefined"

var myMonth; //global variable myMonth

//oberservable array       
function viewModel() {
        this.choices = ko.observableArray([
            "January","February","March","April","May","June",
          "July","August","September","October","November","December"]);

        this.selectedChoice = ko.observable();

        this.selectedChoice.subscribe(function(newValue) {
          myMonth = this.choices.indexOf(this.selectedChoice());
          myLayerGroup.clearLayers();
          myLayerGroup.addLayer(myLayers[myMonth]);
                console.log(myMonth); //works!
                return myMonth; // no effect?!
        },this);
    };
    ko.applyBindings(new viewModel());


    // popUp window content
    function onEachFeature(feature, layer) {
      if (feature.properties) {
      var popupContent = "Selected month: "+ myMonth;
            layer.bindPopup(popupContent);
        }
    }; 
GôTô
  • 7,974
  • 3
  • 32
  • 43

2 Answers2

1

The only issue I see with your code is that the statement

return myMonth; // no effect?!

will absolutely have no effect because it doesn't make any sense inside of a .subscribe function. There's nowhere to return the value to.

Here's a fiddle showing your code working pretty much as-is so I'm unclear what actual problem you're having. Is there an error message? How are you calling onEachFeature?

EDIT 1: With your updated fiddle I can now see that the issue is that your popupContent is being set one time at the very beginning and never updated afterward. The geoJSON function immediately calls your onEachFeature function to get the selected layer's content, which at that time is undefined, and stores that as its content permanently.

The popupContent seems to expect a flat string too so there might not be any way to get that to update dynamically in a knockout binding fashion. I think you'll have to re-create the layer any time the data changes by calling geoJSON again.

Here's an updated fiddle where I moved your geoJSON call into a createLayer function so that it gets called by the subscription to rebuild the layers:

  this.selectedChoice.subscribe(function(newValue) {
    myMonth = this.choices.indexOf(this.selectedChoice());
    myLayerGroup.clearLayers();
    myLayerGroup.addLayer(createLayer(myLayers[myMonth]));
  }, this);

https://jsfiddle.net/jlspake/5rxcvjdw/1/

Jason Spake
  • 4,293
  • 2
  • 14
  • 22
0

What you call a global variable is actually a property of the window object (see this SO post for example).

This comment:

// popUp window content
function onEachFeature(feature, layer) {
  if (feature.properties) {
  var popupContent = "Selected month: "+ myMonth;
        layer.bindPopup(popupContent);
    }
}; 

Makes me think you are trying to access the variable myMonth, defined in the parent window, from a child popup, which is not possible in this way.

You could access the variable with the syntax window.opener.myMonth, as described in this doc.

// popUp window content
function onEachFeature(feature, layer) {
  if (feature.properties && window.opener) {
  var popupContent = "Selected month: "+ window.opener.myMonth;
        layer.bindPopup(popupContent);
    }
}; 
Community
  • 1
  • 1
GôTô
  • 7,974
  • 3
  • 32
  • 43