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 ?

Ilan Frumer
  • 32,059
  • 8
  • 70
  • 84
badaboum
  • 843
  • 2
  • 17
  • 28

3 Answers3

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"); 
    }
  });

});
Ilan Frumer
  • 32,059
  • 8
  • 70
  • 84
  • This was the best solution for my issue, as I kept having scope send the same object over no matter what I did. – Jeff Longo Aug 21 '18 at 22:53
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.

filipe.costa01
  • 238
  • 1
  • 10
Andrew Shustariov
  • 2,530
  • 1
  • 17
  • 17
  • 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. – Sarah_A Jan 07 '18 at 11:10
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)) 
just-boris
  • 9,468
  • 5
  • 48
  • 84
  • I feel like I'm cheating because this worked perfectly and easily without me having to endure a third-degree torture about closures. – Fakeer Mar 05 '19 at 08:16