5

I have an issue with an Angular app.

I have an array that contains langs shortcodes ('en', 'fr', ...). And basically, I want Angular to loop on that array and make HTTP get request on each value.

for (var i in $scope.langs) {
      console.log($scope.langs[i].shortName);
      $http.get($scope.appURL + $scope.langs[i].shortName + '/api/products/?format=json&resto='+ $scope.restoID)
         .then(function(res){
            $scope.products = angular.fromJson(res.data);   
            window.localStorage.setItem("products-"+$scope.langs[i].shortName, JSON.stringify(res.data));
            $scope.products =  JSON.parse(window.localStorage.getItem("products-"+$scope.langs[i].shortName));
            console.log('LANG = '+ $scope.langs[i].shortName, $scope.products);
          });
}

The first log shows :

fr
en

Great ! The last log is thrown twice (I've got 2 langs in my array), great too.

The problem is that in the loop, the log shows the same language in both case, when I should have one fr/api/... and one en/api/... It always log 2 en/api/...

I don't know if it's clear... Any idea ?

4
  • Looks like an async issue! Commented Jun 5, 2014 at 16:07
  • 2
    @Fals It's not. The problem is that the variable i in the anonymous function is bound at the time of executing the function, not the time of creating the function, and it will always have the last key value (i.e. $scope.langs.length - 1) Commented Jun 5, 2014 at 16:11
  • Thanks for that link, I'll try to see what I can do with that. I was afraid that's an async issue, like Fals said. Commented Jun 5, 2014 at 16:14
  • I understand the problem, through the link you gave me, by I can't resolve this on my own I think... Commented Jun 5, 2014 at 16:16

1 Answer 1

17

The problem is that your i variable changes before all your ajax requests return. Therefore, it will always be equal to the $scope.langs.length - 1 when your callback executes. You're going to want to create a closure around each of your $http requests. Angular has some built in functionality for just that:

angular.forEach($scope.langs, function(lang){
  // Here, the lang object will represent the lang you called the request on for the scope of the function
  $http.get($scope.appURL + lang.shortName + '/whatever/you/want', function(res) {
    // Do whatever you want with lang here. lang will be the same object you called the request with as it resides in the same 'closure'
    window.localStorage.setItem(lang.shortName, JSON.stringify(res.data));
  });
});
Sign up to request clarification or add additional context in comments.

1 Comment

I'll try that, I didn't know about angular.forEach, that will surely help me, thanks !

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.