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);
        }
    }; 
0

2 Answers 2

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/

Sign up to request clarification or add additional context in comments.

3 Comments

Hey Guys, thanks a lot for your comments! I put together a jsfiddle which shows my problem.(the window.opener solution did not work for me). JSFIDDLE
@B.Mohr Updated my answer. See Edit 1.
@ Jason Spake: Thanks for your smart solution and your effort! Helped me a lot!
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);
    }
}; 

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.