Jquery match ajax results with index

Hi, I’m having trouble with a problem I get quite often.
I have a series for which I want to make individual ajax requests, but I need to keep track wich results belong to what item. I can’t seen to pass addional parameters into the callback function


refresh2: function(){
    for(var i in myMap.markers){

        $.getJSON('/json/units/position/'+ myMap.markers[i].id, function(data) {
            // Here I need the index i to make sure I update the right marker

        });
    }
}

The only way I can think of is actually sending the index to the server and then have it send back with the data. That’s rather ugly I think, there must be a better way. Any ideas?

You have the function that needs to know about the variable i

function(data) {
    // Here I need the index i to make sure I update the right marker
});

Let’s call that function callback


var callback = ...;
$.getJSON('/json/units/position/'+ myMap.markers[i].id, callback);

Let’s return that callback function from a separate function:


function createCallback() {
    return function(data) {
        // Here I need the index i to make sure I update the right marker
    });
}

When that function is returned, it will retain with it any variables that were in that same function. This is called closure.
If we call the createCallback function with an argument, the returned function will retain knowledge of that argument.


function createCallback(i) {
    return function(data) {
        // Here I need the index i to make sure I update the right marker
    });
}
...
var callback;
for (...) {
    callback = createCallback(i);
    $.getJSON('/json/units/position/'+ myMap.markers[i].id, callback);
}

By the way, do not use for…in to loop over items of an array. While that works in some cases, there are several situations that just cause that to break.
for…in is designed to loop over the properties and methods of an object, not an array. It’s best to use a for loop to loop over arrays instead


var i;
for (i = 0; i < myMap.markers.length; i += 1) {
    ...
}

Remember that with an array you’re not looping through all of the enumerable properties of an object, which is what for…in is designed to do.

Hi Paul,

Thanks for your reply and naming the concept so I can do some more research on it. I think I get the idea, but it’s not working


    refresh2: function(){
    	// Build function that for each marker in myMap.markers:
    	// - get's the latest position
    	// - remove and re-add the marker to the map
    	// - remove the marker from the list and add the updated info, or update it's info in the table
    	var i;
    	for(i = 0; i < myMap.markers.length; i += 1){
        	function createCallback() {
        	    return function(data) {
        	        // Here I need the index i to make sure I update the right marker
        	    	console.log(data);
        	    	console.log(i);
        	    }
        	}
    		
    		var callback = createCallback(i);
    		$.getJSON('/json/units/position/'+ myMap.markers[i].id, callback);
   		
    	}

    },

I have 4 markers.
The console output is still “4” every time and not the index at the moment te request is done. The data is OK, it is the result of the individual requests.
I can’t see my mistake.

Two problems.

  1. Move the createCallback function outside of the loop
  2. Give the createCallback function an argument