Use closure . Let me show you a simple example.
// JavaScript on Client-Side window.onload = function() { var f = (function() { for (i = 0; i < 3; i++) { (function(i){ var xhr = new XMLHttpRequest(); var url = "closure.php?data=" + i; xhr.open("GET", url, true); xhr.onreadystatechange = function () { if (xhr.readyState == 4 && xhr.status == 200) { console.log(xhr.responseText); // 0, 1, 2 } }; xhr.send(); })(i); } })(); }; // Server-Side (PHP in this case) <?php echo $_GET["data"]; ?>
In your case ... wrap the asynchronous call / function with closure
for (var i=0; i< this.selectedAvailableUnits.length; i++) { (function(i) { // <--- the catch var unit = this.selectedAvailableUnits[i]; var unitId = unit.unitId; var url = '/incident/' + currentIncidentId + '/assignUnit/' + unitId $http.post(url).then(function(response) { // DOING SOMETHING }, function(error) { alert(error); }); })(i); // <---- (the i variable might be omitted if it not needed) }
The section below is not directly related to the question, but rather the comments related to this answer.
The example presented in jsFiddle mentioned in the comments and below is an error and as such does not prove anything.
It is true that this snippet, without even using closure, yields "Hello Kitty" three times; in fact, if you replace the console.log() method with alert() , you will see that it gives "Hello Kitty" six, nine, or even twelve times. So, what the hell is going on alone;) how can I get a warning window that appears six, nine or twelve times in a cycle of three iterations ?!
// your example (a) // my comments // var f = (function() { for (i = 0; i < 3; i++) { //(function(){ // this way you can't have multiple scopes var xhr = new XMLHttpRequest(); var url = "closure.php?data=your-data"; // use /echo/html/ for testing on jsfiddle.net xhr.open("GET", url, true); // use POST for testing on jsfiddle.net xhr.onreadystatechange = function () { // this way you might catch all readyStage property values callback(); // this way the callback function will be called several times }; xhr.send(); //})(); } })(); var callback = function() { console.log("Hello Kitty"); // or use alert("Hello Kitty"); };
Output:
GET http:
As you can see, we have an error and nine "Hello Kitty" outputs per line :) Before I change the function described above, we will see two important things
First
onreadystatechange event stores a function or reference that should be called automatically each time the readyState property changes, and the status property contains the status of the XMLHttpRequest object.
readyState Possible property values
- 0: request not initialized
- 1: server connection established
- 2: received request
- 3: processing request
- 4: The request is complete and the response is ready.
status Possible property values
- 200: OK
- 404: Page not found
Second
As I said in the comments, jsfiddle.net is not reliable for testing asynchronous fragments without any changes. In other words, the GET method must be changed to POST , and the url property must be changed to this link /echo/html/ (for more options take a look at jsFiddle )
Now change the example from the above (and follow the comments in the code)
// corrected example (b) // var f = (function() { for (i = 0; i < 3; i++) { //(function(i){ // uncomment this line for the 3rd output var xhr = new XMLHttpRequest(); var url = "/echo/html"; var data = "data"; xhr.open("POST", url, true); xhr.onreadystatechange = function () { //if (xhr.readyState == 4 && xhr.status == 200) { // uncomment this line for the 4th output callback(i, xhr.readyState); // uncomment this line for the 4th output //} }; xhr.send(data); //})(i); // uncomment this line for the 3rd output } })(); var callback = function(i, s) { console.log("i=" + i + " - readyState=" + s + " - Hello Kitty"); };
1st output: // six outputs
(4) i=3 - readyState=1 - Hello Kitty // four outputs related to readyState value 'server connection established' i=3 - readyState=2 - Hello Kitty // related to readyState value 'request received' i=3 - readyState=4 - Hello Kitty // related to readyState value 'request finished and response is ready'
2nd output: // six outputs
(2) i=3 - readyState=1 - Hello Kitty // two outputs related to readyState value 'server connection established' i=3 - readyState=2 - Hello Kitty // related to readyState value 'request received' (3) i=3 - readyState=4 - Hello Kitty // three outputs related to readyState value 'request finished and response is ready'
Without any changes made in example (b), we have two different outputs. As you can see, different outputs for different ReadyState property values ββwere outputs. But the value of i remained the same.
Third conclusion: // after uncommenting the lines for the 3rd output shown above in example (b)
i=0 - readyState=2 - Hello Kitty // related to readyState value 'request received' i=0 - readyState=4 - Hello Kitty // related to readyState value 'request finished and response is ready' i=1 - readyState=2 - Hello Kitty // ... i=1 - readyState=4 - Hello Kitty // ... i=2 - readyState=2 - Hello Kitty i=2 - readyState=4 - Hello Kitty
So, after uncommenting the function that contains i as an argument, we see that the value of i was saved. But this is still not true, since there are six outputs, and we need only three. Since we do not need all the values ββof the readyState property or status of the XMLHttpRequest object, let it uncomment the two lines needed for the fourth output
4th output: // after uncommenting the lines for the 4th output shown above in example (b), finally three outputs
i=0 - readyState=4 - Hello Kitty i=1 - readyState=4 - Hello Kitty i=2 - readyState=4 - Hello Kitty
Finally, it must be the correct version of the fragment, and this is what we need.
Another omnipotent omnipotent mechanism (as I expressively said earlier) was the bind() function, which I do not prefer, since it is slower than closure.