0

I am working on an AngularJS Application. I have the following array:

$scope.fruits = [
 {url1: 'appleColor', url2: 'appleDetail'},
 {url1: 'orangeColor', url2: 'orangeDetail'},
 {url1: 'grapesColor', url2: 'grapesDetail'},                 
];

Now, I am calling HTTP GET requests like this:

for(var i = 0; i < $scope.fruits.length; i++){
   var fruit = $scope.fruits[i];
   getFruitColor(fruit.url1).then(function(color){
      getFruitDetail(fruit.url2).then(function(detail){
         console.log("color is "+ color);
         console.log("detail is "+ detail);
      }):
   });
}

function getFruitColor(url){
   return $http({
        method: 'GET', url: url, params: {} }).then(getFruitComplete, getFruitFailed);
}

function getFruitDetail(url){
    return $http({ method: 'GET', url: url, params: {} }).then(getFruitDataComplete, getFruitDataFailed);
}

function getFruitDataComplete(response) {
    return response.data;
}
        
function getFruitDataFailed(error) {
    $log.error('Failed to get fruit data - '  + error.data);
}
        
function getFruitComplete(response) {
    return response.data;
}
        
function getFruitFailed(error) {
    $log.error('Failed to get fruit- '  + error.data);
}

Now, since all of these calls would be asynchronous, I expected these calls in NETWORK Tab like this (order of these calls can be different because of asynchronous nature):

getFruitColor('appleColor')

getFruitColor('orangeColor')

getFruitColor('grapesColor')

getFruitDetail('appleDetail')

getFruitDetail('orangeDetail')

getFruitDetail('grapesDetail')

But what I am actually seeing in NETWORK Tab is this:

getFruitColor('appleColor')

getFruitColor('orangeColor')

getFruitColor('grapesColor')

getFruitDetail('grapesDetail')

getFruitDetail('grapesDetail')

getFruitDetail('grapesDetail')

I am a beginner in AngularJS and Javascript and I don't understand what is the issue here and why in the inner HTTP Call, url2 of last element of fruits array is going on for every element in loop. Can anyone please explain why this behavior is happening here? And what I should do to achieve the desired result?

Community
  • 1
  • 1
WarWithSelf
  • 565
  • 1
  • 10
  • 36

1 Answers1

2

try to use let (or const) instead of var for this assignment: var fruit = $scope.fruits[i];. something like that should do the trick:

for(var i = 0; i < $scope.fruits.length; i++) {
   const fruit = $scope.fruits[i];
   getFruitColor(fruit.url1).then(function(color) {
      getFruitDetail(fruit.url2).then(function(detail) {

also consider using let i for the iteration (for(let i = ...).

note that var would be hoisted to the outer scope and each iteration would overwrite the same variable. all calls to getFruitDetail will use only the latest value of fruit which is why you see 3 calls with grapesDetail.

the key difference between var and let/const is that var is function scoped, while let/const are block scoped. this link could be of interest: https://dev.to/sarah_chima/var-let-and-const--whats-the-difference-69e (or a google search for the difference between var/let/const)

groetzi
  • 158
  • 1
  • 7