3

my code look like this:

if (ACTIVETICKETS.length > 0) 
{
    for (var m in  ACTIVETICKETS) 
    {
        if (ACTIVETICKETS.hasOwnProperty(m)) 
        {
            var marker = new L.Marker(new L.LatLng(ACTIVETICKETS[m].location.x, ACTIVETICKETS[m].location.y));
            createHtmlForPopUp(m, function(data)
            {
                console.log(m);
                marker.bindPopup( data ); // calling a function with callback
                tile_layer.addLayer(marker);                           
            });
        }
    } // for loop ends here
}

While executing this, I am getting only the last iteration of m. Total length of ACTIVETICKETS array is 16. So I am getting only 15 entered 16 time

4
  • Ok, that's a classical problem, let's just look for another identical question to close this one. Commented Jul 5, 2013 at 14:54
  • In the meantime Akbar Ali, look up the concept of closure. Commented Jul 5, 2013 at 14:55
  • you function only runs after the loop is finished. Commented Jul 5, 2013 at 14:56
  • 1
    This one is similar but more complex : stackoverflow.com/questions/14791158/… Commented Jul 5, 2013 at 14:56

3 Answers 3

2

The code below should work, but as I commented above, please read about closure so you know why.

    if (ACTIVETICKETS.length > 0) {
      for (var m in  ACTIVETICKETS) {
        (function(x) {
          if (ACTIVETICKETS.hasOwnProperty(x)) {
            var marker = new L.Marker(new L.LatLng(ACTIVETICKETS[x].location.x, ACTIVETICKETS[x].location.y));
              createHtmlForPopUp(x, function(data){
                console.log(x);
                marker.bindPopup( data ); // calling a function with callback
                tile_layer.addLayer(marker);
              });
          }
        })(m);
      } // for loop ends here
    }
Sign up to request clarification or add additional context in comments.

Comments

1

The problem you have is that the value of m, by the time the callback is called, it the one of end of loop. A solution is to protect this value by setting it as value of a variable in an immediately called function :

for (var m in  ACTIVETICKETS) {
   (function(m){
        if (ACTIVETICKETS.hasOwnProperty(m)) 
        {
            var marker = new L.Marker(new L.LatLng(ACTIVETICKETS[m].location.x, ACTIVETICKETS[m].location.y));
            createHtmlForPopUp(m, function(data)
            {
                console.log(m);
                marker.bindPopup( data ); // calling a function with callback
                tile_layer.addLayer(marker);                           
            });
        }
    })(m);
 } // for loop ends here

This is because JavaScript doesn't have block scope, and only creates a new variable scope when a function is invoked.

You can use the same technique with a named function instead of an inline one as above:

function makeTicket(m){
  if (ACTIVETICKETS.hasOwnProperty(m)) 
  {
        var marker = new L.Marker(new L.LatLng(ACTIVETICKETS[m].location.x, ACTIVETICKETS[m].location.y));
        createHtmlForPopUp(m, function(data)
        {
            console.log(m);
            marker.bindPopup( data ); // calling a function with callback
            tile_layer.addLayer(marker);                           
        });
    }
}

Then do this:

for (var m in  ACTIVETICKETS) {
    makeTicket(m)
} // for loop ends here

And as a side note, there are very compelling reasons to not use a for-in enumeration on Arrays, but rather to use a typical for loop, and you don't need the outside if test, so you could remove it and just do

for (var m =0; m<ACTIVETICKETS.length; m++) {
    makeTicket(m)
}

Comments

0

You need to create a closure over all the variables you want to access in the callback function.

    createHtmlForPopUp(m, (function (m, data, marker) {
        return function(data)

        {
            console.log(m);
            marker.bindPopup( data ); // calling a function with callback
            tile_layer.addLayer(marker);                           
        }
    })(m, data, marker));

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.