Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

calling HTTP requests in angularjs in batched form?

I have two for loops and an HTTP call inside them.

for(i=0;i<m;i++) {
  for(j=0;j<n;j++) {
    $http call that uses i and j as GET parameters
    .success(//something)
    .error(//something more)
  }
}

The problem with this is it makes around 200-250 AJAX calls based on values of m and n. This is causing problem of browser crash when tried to access from mobile. I would like to know if there is a way to call HTTP requests in batched form (n requests at a time) and once these calls are finished, move to next batch and so on.

like image 232
user2987346 Avatar asked Nov 13 '13 10:11

user2987346


People also ask

What is http batch request?

A batch request is a single standard HTTP request containing multiple Compute Engine API calls, using the multipart/mixed content type. Within that main HTTP request, each of the parts contains a nested HTTP request. Each part begins with its own Content-Type: application/http HTTP header.

Is HTTP request is synchronous or asynchronous in AngularJS?

The problem is as follows, $http. get is asynchronous, before the response is fetched, the function returns. Therefore the calling function gets the data as empty string.

What is $HTTP in AngularJS?

$http is an AngularJS service for reading data from remote servers.

How do you modify the $HTTP request default Behaviour?

To add or overwrite these defaults, simply add or remove a property from these configuration objects. To add headers for an HTTP method other than POST or PUT, simply add a new object with the lowercased HTTP method name as the key, e.g. $httpProvider. defaults.


3 Answers

You could always use a proper HTTP batch module like this angular-http-batcher - which will take all of the requests and turn them into a single HTTP POST request before sending it to the server. Therefore it reduces 250 calls into 1! The module is here https://github.com/jonsamwell/angular-http-batcher and a detailed explanation of it is here http://jonsamwell.com/batching-http-requests-in-angular/

like image 83
Jon Avatar answered Oct 11 '22 03:10

Jon


Yes, use the async library found here: https://github.com/caolan/async

First, use the loop to create your tasks:

var tasks = []; //array to hold the tasks
for(i=0;i<m;i++) {
  for(j=0;j<n;j++) {
    //we add a function to the array of "tasks" 
    //Async will pass that function a standard callback(error, data)
    tasks.push(function(cb){
       //because of the way closures work, you may not be able to rely on i and j here
       //if i/j don't work here, create another closure and store them as params
       $http call that uses i and j as GET parameters
       .success(function(data){cb(null, data);})
       .error(function(err){cb(err);});
    });
  }
}

Now that you've got an array full of callback-ready functions that can be executed, you must use async to execute them, async has a great feature to "limit" the number of simultaneous requests and therefore "batch".

async.parallelLimit(tasks, 10, function(error, results){
    //results is an array with each tasks results.
    //Don't forget to use $scope.$apply or $timeout to trigger a digest
});

In the above example you will run 10 tasks at a time in parallel.

Async has a ton of other amazing options as well, you can run things in series, parlallel, map arrays, etc.It's worth noting that you might be able to achieve greater efficiency by using a single function and the "eachLimit" function of async.

like image 41
Jonathan Rowny Avatar answered Oct 11 '22 05:10

Jonathan Rowny


The way I did it is as follows (this will help when one wants to call HTTP requests in a batch of n requests at a time )

call batchedHTTP(with i=0);

batchedHTTP = function() {
  /* check for terminating condition (in this case, i=m) */
  for(j=0;j<n;j++) {
    var promise = $http call with i and j GET parameters
    .success(// do something)
    .error(// do something else)

    promisesArray.push(promise);
  }
  $q.all(promisesArray).then(function() {
    call batchedHTTP(with i=i+1)
  });
}
like image 45
user2987346 Avatar answered Oct 11 '22 03:10

user2987346