0

I am attempting to make sequential post requests with angular just changing the request body. The reason for this is I have a REST API that I am calling to create users but it takes some time to return. I wanted to basically send up the requests in batches essentially calling the same endpoint just different request body. I have seen other questions about calling functions sequentially but they always seem to be a set number of functions that do different things. I just can't wrap my brain around the obvious recursion here.

So far I have this function that returns the promise but I don't understand how to write the recursion to call this function to go through all of $scope.csvResults.

$scope.importUsersPromise = function(currentIndex, step) {

    var nextInput = $scope.csvResults.slice(currentIndex, currentIndex+step);

    var requestBodyUsers =  {
                                "mode": "SCRIPT",
                                "inputParams": [
                                    JSON.stringify(nextInput)
                                ]
                            };

    return  $http({
      method: 'POST',
      url: api_url + "v1/serverAction/",
      headers: {
          "Authorization":"user",
          "Content-Type":"application/json"
     },
     requestBodyUsers
    });
};
4
  • Make the function a promise using $q and you could push the promise in an array and resolve using $q.all() when all the request are done. Commented May 17, 2017 at 3:31
  • @MuhammedNeswine, $q.all places no guarantee on the sequential execution of all argument promises, which the OP needs. Commented May 17, 2017 at 3:54
  • Are you just trying to step through each item in the csvResults Array and send that info with an http request? Commented May 17, 2017 at 4:46
  • @JoshuaFoxworth, yes basically. but since each http request is using the same script through this vendors api, I was thinking I needed to do this in batches sequentially to be safe. Then just show the end user a loading bar of some kind. Commented May 17, 2017 at 13:13

2 Answers 2

0

Say you have an array users with all the different request bodies. Then you do something like this:

var users = [/* your request bodies */];

var errors = [/* will store the errors */];

// make the first api call
var promise = apiCall(users[0]);

// use .reduce to chain all requests
promise = users.slice(1).reduce(function(promise, user){

    return promise.then(apiCall.bind(null, user));
}, promise);

promise
    .then(function(){
        // do something when all users are inserted
    })
    .finally(function(){
        // do something when all requests are done
        // even if some of them have failed
        console.log(errors);
    })

function apiCall(user) {
    return $http({... })
}

You have to keep in mind that if one of the requests fails the chain is broken and the following requests will not be send. If you want to send them anyway you should use .finally and optionally .catch to collect the errors:

// use .reduce to chain all requests
promise = users.slice(1).reduce(function(promise, user){

    return promise
          .catch(err => errors.push(err)) // fail handler (optional)
          .finally(apiCall.bind(null, user)); // always make the next api call
}, promise);

It is good idea for you to check angular's documentation if not already ;)

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

3 Comments

I will have to look more into .reduce but otherwise this looks good.
I have implemented your solution and it works great. @user3629092, when I try with the error handler it still will stop if an error such as timeout on a request is hit. From the code it looks like it should hit the err clause and just push the error to the array. I don't see this happening.
My bad. I am used to the native Promise implementation and seems there are some differences. I have modified the example so that it works as expected with the angular's $q implementation of promises.
0

You can put all the request set in a requestArray.

Please check out this link.

Comments

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.