Anish S.
Anish S.

Reputation: 63

AngularJS HTTP post call thru a for loop

I have an array that I'm passing to a payload that will be posted to an API. In the array are field names that the API will take individually( not as an array) so I created a for loop to iterate thru the array and add the field names to the payload dynamically. But when I make the call, I get data for only the last field name. If I have say a total of 6 items in the array, I get data for just the last field.

function getData(payload, index, field) {

        var deferred = $q.defer();


        for (var i = 0; i < field.length; i++) {
            if (field[i]) {

                console.log("terms logged", field[i]);

                var termsData = {
                    user_selection: payload,
                    index_info: index,
                    field: field[i]
                };

                console.log("terms data", termsData);

            } 
          }
                $http({
                    url: 'API',
                    method: "POST",
                    data: $.param(termsData),
                    headers: {'Content-Type': 'application/x-www-form-urlencoded'}
                }).then(function (response) {
                    var data = response.data;

                    console.log("response data", data);

                    deferred.resolve(data);
                });

                return deferred.promise;    
    }

Do I need to repeat the loop after the initial call? Since it's in a for loop, I assumed the calls would be made one after another until the condition is met.

Upvotes: 0

Views: 3314

Answers (2)

matt
matt

Reputation: 91

There are a couple of errors here. First, the return deferred.promise; will break out of the function the first time it is reached. So that's why it's only sending the first term. If you move the return statement outside of the for loop you should get all the terms sent.

What also should be fixed is you have only 1 deferred object attached to multiple calls. There should be a deferred object for each call. Below is an example.

function getData(payload, index, field) {


  for (var i = 0; i < field.length; i++) {
    if (field[i]) {

      console.log("terms logged", field[i]);

      var termsData = {
        user_selection: payload,
        index_info: index,
        field: field[i]
      };

      postTerm(term);
    }
  }
}

function postTerm(term) {
  var deferred = $q.defer();

  console.log("terms data", term);

  $http({
    url: 'API',
    method: "POST",
    data: $.param(term),
    headers: {
      'Content-Type': 'application/x-www-form-urlencoded'
    }
  }).then(function(response) {
    var data = response.data;

    console.log("response data", data);

    deferred.resolve(data);
  });


  return deferred.promise;
}

Upvotes: 3

Italo Ayres
Italo Ayres

Reputation: 2663

I believe what you are looking for is a way to chain promises within a loop. This can be achieved storing the promises inside an array as this:

var promises = [];
for(...) {
    var promise = $http(...); // http calls return a promise
    promises.push(promise);

    // Or, if you prefer to use $q
    var deferred = $q.defer();
    $http(...).success(function(){
        deferred.resolve();
    });
    promises.push(deferred);
}

$q.all(promises).then(function(){
    // This will be executed when all promises inside the array have been resolved
});

Although, I do not recommend doing so many requests. If possible, change your backend, enabling it to receive an array of objects alternatively.

Here some documentation about $q https://docs.angularjs.org/api/ng/service/$q

Resolve a promise array with Angular UI Router

Upvotes: 1

Related Questions