14

I would like to know if it's possible to use while or for with a nested call to $http.get:

This is an example:

for (var i = 0; i < $scope.comments.length; i++) {
   alert($scope.comments[i].id); // = 2
   $http.get('/api/logged/like/isliked?id=' + $scope.comments[i].id).success(function(data, status, header, config) {
        alert('Test');
        alert($scope.comments[i].id); // Not executed.
   }).error(function(data){alert('The requeste isn't working');}); }

I put two alerts to display the id of my comment I'm using to retrieve JSON. I get the id with the first alert, then 'Test' for the second, but the third alert isn't displaying. Why not?

Here an example of the JSON:

{data":[
   {"id":2,"is_liked":false,"nb_comments":1,"nb_likes":1,
    "date_creation":"2014-05-26T17:03:54+0000"},
   {"id":1,"is_liked":true,"nb_comments":0,"nb_likes":1,
    "date_creation":"2014-05-26T17:00:26+0000"}
]}
1
  • 1
    Are you sure it's such a good idea to do an HTTP request for every single comment...? Commented May 28, 2014 at 21:49

2 Answers 2

33

The problem:

Don't make functions inside of a loop ...

Each call of your function is actually referencing the same copy of i in memory. A new closure is created each time the for loop runs, but each one captures the same environment. Therefore, every call to $http.get (an asynchronous function) results in the firing of a callback referencing the same final value of i from the end of loop.

A solution:

Pass i as a parameter to a separately defined function:

var getIsLiked = function(i){
  $http.get('isliked.json' + $scope.comments[i].id)
    .success(function(data) {
      console.log('Test');
      console.log('i is ', i);
      console.log($scope.comments[i].id);
  }).error(function(data){console.log("The request isn't working");}); }
}

for (var i = 0; i < $scope.comments.length; i++) {
  getIsLiked(i);
}

Demo

This can be really hard to wrap your head around, but it's worth the time to understand deeply. Not only will it help you to avoid similar problems in the future, it will also give you a better understanding of closures, an important concept in JavaScript.

Sign up to request clarification or add additional context in comments.

1 Comment

I tried what you advice and that works thanks a lot @MarcKline
-1

The third alert is inside the error callback of your $http.get promise. It will only be executed if the request fail. The two first alert will be executed if the request pass OR the third one will be launched if it fails.

4 Comments

there are 2 alerts on success one outside and one on error
Ok, I don't see why this alert is not called. Could you provide a example of your bug with a service like Plunker. It will help me fix your bug.
Thx for your help but @Dawson find the solution
As noted, that answer does not solve your problem.

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.