I. Bilous
I. Bilous

Reputation: 57

Sequential http requests inside a loop

In my AngularJS application I can have different number of http requests to perform sequentially. I think that I need a loop for this purpose:

for (let i = 0; i < $scope.entities.length; i++) {
    MyService.createFixedValue($scope.id, $scope.entities[i]);
}

where MyService.createFixedValue is http POST request:

service.createFixedValue = function(property_id, fixed_value_entity){
    return $http({
        method: 'POST',
        url: '/my_url'
        headers: {
            'Content-Type': 'application/json'
        },
        data: fixed_value_entity
    });
}

But in this case my requests are asynchronous. What changes I need to do to get a sequential requests?

Upvotes: 1

Views: 2232

Answers (3)

georgeawg
georgeawg

Reputation: 48968

To make HTTP requests sequentially, use $q.all and array.reduce:

var sequentialPromise = $scope.entities.reduce( (p, ent)  => {
    var pn = MyService.createFixedValue($scope.id, ent);
    var valuePromise = pn.then(response => response.data);
    var newP = p.then( vArr => {
        return $q.all([...vArr, valuePromise]);
    });
    return newP;
}, $q.when([]) );

sequentialPromise.then(valueArr => {
    console.log(valueArr);
}).catch(error => {
    console.log(error);
});

For more information, see

Upvotes: 1

Emiel Zuurbier
Emiel Zuurbier

Reputation: 20944

Sequential Requests (Not recommended)

Use for...of to and async / await to create a sequential loop of HTTPRequests.

Build a async function like the example below.

async function createFixedValues(id, entities) {
  for (const entity of entities) {
    await MyService.createFixedValue(id, entity);
  }
}

And call it by injecting the $scope properties.

createFixedValues($scope.id, $scope.entities);

Single Request and sending an array (recommended)

It will be easier to just send the entire array in a single HTTPRequest instead of sending a request for each entity. The result will be the same but a single request will be more efficient.

service.createFixedValue = function(property_id, fixed_value_entities) {
  return $http({
    method: 'POST',
    url: '/my_url'
    headers: {
      'Content-Type': 'application/json'
    },
    data: fixed_value_entities
  });
}

Give the entire $scope.entities array as the second argument.

MyService.createFixedValue($scope.id, $scope.entities);

You'll have to modify the server side of the request for you are now sending an array instead of a single value. But you have not specified how you handle your server side response, so that is up to you.

Upvotes: 4

mrApau
mrApau

Reputation: 1

Maybe try not returning an http POST request. In fact, you may not need to return anything in the function. Just do the post request. If you need to capture the response, push it in a global array.

Upvotes: 0

Related Questions