5

I'm working on an angularJS app and this is my first website using this framework. In my app i've a need to make a $http call inside a for loop. With in the loop before the next iteration I want to wait for the response from my previous call. What is the best and simple way to do this. I've tried using the callBack, $q.all(), .then in all of these only the last request is going through. Please help.

Note: My API that i'm calling through $http can't queue requests.

Edit: I've tried both the below approaches, in both of the cases only the last request is being made successfully. Can you tell me what is wrong i'm doing here.

Approach 1:

var promiseArray=[];

for(var i=0;i<items.length;i++)
{
 var promise=services.Post(items[i]);
 promiseArray.push(promise);
}

$q.all(promiseArray).then(data)
{
 ...
}

Approach 2:

var promises = [];

for (var i = 0; i < items.length; i++) {

    var deffered = $q.defer();
    var promise = services.Post(items[i]);
    promise.success(function(data) {
        deffered.resolve(data);
    })
    promises.push(deffered);
}

var result = $q.all(promises);

EDIT :2 Service Code:

Services.Post = function(lineItemId, submitUrl) {
    var url = (submitUrl) ? submitUrl : Services.serviceUrl;

    return $http.post(url, {
        "LineItemID": lineItemId
    }).
    success(function(data, status, headers, config) {
        Services.processResponse(data, status, headers, config);
    }).
    error(function(data, status, headers, config) {

        JL('Angular').error('Error response when calling Service ' + config);

    });
};
Pankaj Parkar
  • 134,766
  • 23
  • 234
  • 299
Ajay Srikanth
  • 1,095
  • 4
  • 22
  • 43
  • take a look at the async lib (https://github.com/caolan/async) you could load it on the browser via browserify/webpack/jspm – Felipe Skinner Apr 23 '15 at 18:38

1 Answers1

6

You could use $q.when which would take promise of $http & when it gets resolved it call the function inside .then

$q.when(promiseObj).then(callback);

If there are multiple promise then you could use $q.all which would accept array of promise & called then function when all promise inside the function gets resolved.

$q.all([promiseObj1, promiseObj2]).then(callback);

Update

I think your 1st approach is right only missed couple thing

  1. for loop condition, which does create an extra object which would be undefined
  2. $q.all should have function inside .then

Code

var promiseArray=[];

for(var i=0; i < items.length - 1;i++) //<-- change from i<items.length
{
 var promise=services.Post(items[i]);
 promiseArray.push(promise);
}

$q.all(promiseArray).then(function(data) //<-- it should be function in .then
{
  //this will called after all promises get resolved.
});
Pankaj Parkar
  • 134,766
  • 23
  • 234
  • 299
  • Hi Pankaj, thanks for the response, I've tried different approaches that i've mentioned above. Please take a look at it and correct me if there is anything wrong. – Ajay Srikanth Apr 23 '15 at 19:30
  • @AjaySrikanth your first approach looks cool to..I think in angular service you didn't return a promise, you should have to return promise from service..if you have any doubt then..add you angular service code too..I'll help with that code too – Pankaj Parkar Apr 23 '15 at 20:39
  • Thanks for extending your help, i've copied my service code here, could you please take a look at it – Ajay Srikanth Apr 23 '15 at 21:08
  • This didn't help me actually, as the service that I'm calling can't queue the requests and can handle requests one after the other. – Ajay Srikanth May 08 '15 at 19:58
  • @AjaySrikanth you want to maintain synchronize queue? – Pankaj Parkar May 08 '15 at 20:00
  • yes as my service can't handle the queue, I want my code to stop moving further until the last iteration of my for loop is completed before it executes anything else after the for loop. – Ajay Srikanth May 11 '15 at 21:05
  • oh..but currently your code is looking for run code after all bunch of promises get complicated.. – Pankaj Parkar May 12 '15 at 00:28