andreiho
andreiho

Reputation: 326

Breaking down an HTTP request to the same API into several HTTP requests

I have an API /api/organizations/ that takes limit and offset as query parameters and returns by default 100 items if no limit is specified.

For performance reasons, the API will return a maximum of 100 items at once. But let's say I want all the available data. How would I go about calling the same endpoint multiple times and building the data object to be assigned to the scope only when all the data has been retrieved?

The API returns by default the total count of the items, so from the first request I know how many items I have to retrieve, but I'm not sure how to go about processing the requests in a smart way.

I could make the first call, save the response in a variable, and then keep incrementing the offset and making new calls until I reach the end, but I'm wondering if there's a better way to do this.

I am using the angularjs $resource service.

Upvotes: 1

Views: 404

Answers (1)

andreiho
andreiho

Reputation: 326

I managed to do this in a fairly small number of lines of code, using the angular's $q service. I'll post this as the answer, but if there's an even better way to do this considering the use case, I'll happily update the correct answer.

First I define the array that will hold the promises:

Then I make the first call to the API, and I limit the response to one item, because all I need from this call is the count which is the total number of items I expect to have when I finish everything.

Inside this call I build the promises array based on my limit and the total number of available items returned by the first call and then run $q.all. When all promises have resolved, I put everything together.

var promises = [];
var limit = 100;

Organizations.get({ limit: 1 }, function(response) {

  // set the number of promises the array will need to contain
  var promisesCount = _.ceil(response.total / limit);

  // push x promises to the array, incrementing the offset each time
  _.times(promisesCount, function(n) {
    promises.push(Organizations.get({ limit: limit, offset:  limit * n }).$promise);
  });

  // run everything at the end and put the results together
  $q.all(promises)
    .then(function(data) {
      $scope.organizations = _.flatten(_.pluck(data, 'rows'));
    });

});

Upvotes: 1

Related Questions