1

In my angular application, I have a piece of code like this

for (var i = 0; i < $scope.itemList.length; i++) {
    if ($scope.itemList[i].serialNumber == quickCode) {
        console.log(i)
        returnsService.getNoReceiptErrorMessages($scope.itemList[i].sku, quickCode).then(function (response) {
            console.log(i)

            }
    }
}

Its just a for loop and in side the loop there is an angular service to call backend api. The array have just one item only. So the value of i is expected to be 0 all the time. But the console.log(i) before the service call print 0 and after service call prints 1. Can some one point out what is happening here.

1
  • 1
    I believe this is due to the nature of js for loops, and scoping. jsfiddle.net/8ncqeoeq illustrates that i will be 1 after the loop; I believe that the callback will be referencing the state of i as it runs, which is 1, rather than the i which is passed. I'll try and formulate this into a proper answer Commented May 11, 2017 at 10:03

2 Answers 2

2

the callback that you pass to the .then method is a closure, that for loop will keep going when the async call happens and the counter will keep incrementing.

A closure execution context has a pointer to the outer scope and all its variables, what you're experiencing here is that when the callback is fired as well as the console.log the loop has already finished and the i counter (available in the execution context) will be equals to the size of the array that is 1.

to keep the actual counter in the callback you could wrap the service call inside an immediatly invoked function (that creates an isolated scope) passing the actual counter as an argument.

(function(count){ 
  //here i will be detached scoped to this function
  returnsService.getNoReceiptErrorMessages($scope.itemList[count].sku, 
   quickCode).then(function (response) {
    console.log(count)
  }
})(i)
Sign up to request clarification or add additional context in comments.

Comments

1

It's problem of closure, that's why let(ReadMore) came into the picture, replace var by let, will solve your problem. or If you not using ECMA6 then enclose your call, Like :

(function(variable){
  // variable scope remain intact here 
})(variable)

Here is your problem specific section in above link

See also this Fiddle

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.