1

I try to fetch multiple json files in a loop. The data gets fetched, but in my callback function I'm left with the last key of the loop for each result.

Here is the caller:

deckbuilderApp.factory('DeckFactory', ['$http', '$rootScope', 'DataFactory', function($http, $rootScope, DataFactory) {

  var cardColors = {"white":{}, "blue":{}, "black":{}, "red":{}, "green":{}, "colorless":{}};
  var cardColorsCheck = {"white":true, "blue":true, "black":true, "red":true, "green":true, "colorless":true};

  return {
    fetchCardColors: function() {
      for (key in cardColors) {
        if (cardColors.hasOwnProperty(key)) {
          DataFactory.cardColors(key, function(cardIds) {
            console.log("GOT COLORS FOR " + key);
            cardColors[key] = cardIds;
          });
        }
      }
    }
  }
}

And the callee:

deckbuilderApp.factory('DataFactory', function($http) {
  return {
    cardColors: function(color, callback) {
      $http({
        method: 'GET',
        url: 'js/cardColors/' + color + '.json'
      }).success(callback)
    }
  }
}

The data that gets fetched is legit, but the log line always prints "GOT COLORS FOR colorless" the last of the keys.

1
  • 1
    it's because your cardColours function is async. The callback is being invoked after the loop finished. Commented Aug 21, 2015 at 10:25

1 Answer 1

2

This is the same as evaluating

for (var i = 0; i < 100; i++) {
    setTimeout(function () {
        console.log(i);
    }, 0)
}

You will get 100 times number 100 logged into the console.

This is because of the contents of your for loop are async.

To prevent this you may use let (closure, iife, etc.):

for (var i = 0; i < 100; i++) {
    (function (i) {
        setTimeout(function () {
            console.log(i);
        }, 0)
    })(i)
}

This pattern is so common that in new JavaScript (ES6) there is a let keyword:

for (let i = 0; i < 100; i++) {
    setTimeout(function () {
        console.log(i);
    }, 0)
}
Sign up to request clarification or add additional context in comments.

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.