Tropicalista
Tropicalista

Reputation: 3137

Subsequent ajax calls in angularJs

I'd like to make subsequent ajax calls in angularJs inside a service.

I've tried with something like this:

var requests = [
    {'url': 'call1'},
    {'url': 'call2'},
    {'url': 'call3'}
];

return $q.all([
    $http({
        url: requests[0],
        method: "POST"
    }).then( /*callback*/ ),
    $http({
        url: requests[1],
        method: "POST"
    }).then( /*callback*/ )
]);

But this make alla ajax in parallel. I need a way to make this calls subsequent, so after first end, it calls second....

Upvotes: 4

Views: 2013

Answers (3)

Dan Ross
Dan Ross

Reputation: 3701

You could use async.eachSeries:

var requests = ['call1', 'call2', 'call3'];

function iterator(request, done) {
    $http({
        url: request,
        method: "POST"
    }).then(done);
};

async.eachSeries(
    requests,
    iterator,
    function (err) {
        // Done
    }
);

From the readme:

eachSeries(arr, iterator, callback) The same as each only the iterator is applied to each item in the array in series. The next iterator is only called once the current one has completed processing. This means the iterator functions will complete in order.

  • arr - An array to iterate over.
  • iterator(item, callback) - A function to apply to each item in the array. The iterator is passed a callback(err) which must be called once it has completed. If no error has occured, the callback should be run without arguments or with an explicit null argument.
  • callback(err) - A callback which is called after all the iterator functions have finished, or an error has occurred.

Upvotes: 2

Michal Charemza
Michal Charemza

Reputation: 27032

You should be able to call another $http call in the "then" callback, returning the return value of $http

$http({...})
.then(function() {
  return $http({...});
 })
.then(function() {
  return $http({...});
});

This works because each call to $http returns a promise. If you return a promise in the "then" success callback, then the next "then" callback in the chain will be deferred until that promise is resolved, which will be when the ajax call completes.

Edit: In response to the comment, you can loop over an array of requests:

var requests = [
   {'url':'call1','method':'get'},
   {'url':'call2','method':'get'},
   {'url':'call3','method':'get'}
];

var promise = null;
angular.forEach(requests, function(details) {
  promise = $q.when(promise).then(function() {
    return $http(details);
  });
});

As in the Plunker at http://plnkr.co/edit/RSMN8WuPOpvdCujtrrZZ?p=preview . The $q.when is just for the first value of the loop, when promise is set to null, so it has a then callback that is called immediately.

Upvotes: 1

Valentyn Shybanov
Valentyn Shybanov

Reputation: 19391

You can chain promises:

  var requests =[{'url':'index.html'},
               {'url':'index.html'},
               {'url':'index.html'}];

function makeCall(n) {
  return $http({url:requests[n].url+"?n="+n,method:"GET"}).then(function(r) {
     if (n+1<requests.length) return makeCall(n+1);
  });
}
   makeCall(0);

http://plnkr.co/edit/1HdYUtHKe8WXAFBBq8HE?p=preview

Upvotes: 2

Related Questions