2

When I loop through the $http post service for Angularjs

for (var i = 0; i < $scope.tagStyles.length; i++) {
  $scope.profilTag.tag = $scope.tagStyles[i].id_tag;
  $scope.profilTag.texte = $scope.tagStyles[i].style ;
  $scope.profilTag.profil = lastDocId;

  $http.post('/ajouterProfilTag',$scope.profilTag) 
  .success(function(data){ 
    if (data=='err'){ 
      console.log("oops"); 
    }     
  });
};

I get just the last element in my database. Is it something related to asynchronous call ?

4
  • And what do you mean by 'looping'? Can't see any loop in your code. Commented Jan 9, 2014 at 12:33
  • @AndreyShustariov i mean by looping that i have added the $http.post inside a for loop Commented Jan 9, 2014 at 14:21
  • Well, callback of success method is asynchronous. It executes in the future. Maybe even after your loup is done. Commented Jan 9, 2014 at 14:23
  • @AndreyShustariov i have edited the post and what i need to do is to call the $http.post inside the loop any ideas ? is there a way to make the call back of success method synchronous ? Commented Jan 9, 2014 at 14:24

3 Answers 3

9

$http docs:

The $http service will not actually send the request until the next $digest() is executed.

What probably happens is that $scope.profilTag is being passed by reference to $http and only being sent after a $digest. You override that reference each iteration and that's why you only left with your last item.

Be aware that functions has scopes but for loops don't!

Try this instead:

$scope.tagStyles.forEach(function(item){
  var profilTag = {
    tag: item.id_tag,
    texte: item.style,
    profil: lastDocId,
  };

  $http.post('/ajouterProfilTag',profilTag) 
  .success(function(data) { 
    if (data=='err'){ 
      console.log("oops"); 
    }
  });

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

1 Comment

This was the best solution for my issue, as I kept having scope send the same object over no matter what I did.
7

You may want to use AngularJs promise API.

var promiseArray = [];

for (/*your loop statements*/) {
 promiseArray.push($http.post('/url', $scope.var));
}

$q.all(promiseArray).then(function(dataArray) {
    // Each element of dataArray corresponds to each result of http request.
});

See Usage->returns section in $http service docs, to understand what is returned via dataArray parameter.

1 Comment

it worked for me better that Ilan's answer, because it kept all requests in an array and sent them one after the other without any interrupt. Ilan's answer let other requests to be sent in between, which was not desirable for my case.
3

It is happened because request makes asynchronously. Real requests are sending after all iterations have completeted. Try send copy of params like this

$http.post('/ajouterProfilTag',angular.copy($scope.profilTag)) 

1 Comment

I feel like I'm cheating because this worked perfectly and easily without me having to endure a third-degree torture about closures.

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.