Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular promise on multiple $http

I am trying to do multiple $http call and my code looks something like this:

var data = ["data1","data2","data3"..."data10"];

for(var i=0;i<data.length;i++){
    $http.get("http://example.com/"+data[i]).success(function(data){
        console.log("success");
    }).error(function(){
        console.log("error");
    });
}

How can I have the promise to know all $http call is successfull? If anyone of it fail, will perform some action.

like image 881
user1995781 Avatar asked Sep 26 '15 06:09

user1995781


2 Answers

You could also use $q.all() method.

So, from your code:

var data = ["data1","data2","data3"..."data10"];

for(var i=0;i<data.length;i++){
    $http.get("http://example.com/"+data[i]).success(function(data){
        console.log("success");
    }).error(function(){
        console.log("error");
    });
}

You could do:

var promises = [];
data.forEach(function(d) {
  promises.push($http.get('/example.com/' + d))
});
$q.all(promises).then(function(results){
  results.forEach(function(data,status,headers,config){
    console.log(data,status,headers,config);
  })
}),

This above basically means execute whole requests and set the behaviour when all have got completed.

On previous comment:

Using status you could get to know if any have gone wrong. Also you could set up a different config for each request if needed (maybe timeouts, for example).

If anyone of it fail, will perform some action.

From docs which are also based on A+ specs:

$q.all(successCallback, errorCallback, notifyCallback);
like image 196
diegoaguilar Avatar answered Oct 28 '22 23:10

diegoaguilar


If you are looking to break out on the first error then you need to make your for loop synchronous like here: Angular synchronous http loop to update progress bar

var data = ["data1", "data2", "data3", "data10"];
$scope.doneLoading = false;
var promise = $q.all(null);

angular.forEach(data, function(url){
  promise = promise.then(function(){
    return $http.get("http://example.com/" + data[i])
      .then(function (response) {
        $scope.data = response.data;
      })
      .catch(function (response) {
        $scope.error = response.status;
      });
  });
});

promise.then(function(){
  //This is run after all of your HTTP requests are done
  $scope.doneLoading = true;
});

If you want it to be asynchronous then: How to bundle Angular $http.get() calls?

app.controller("AppCtrl", function ($scope, $http, $q) {
  var data = ["data1", "data2", "data3", "data10"];
  $q.all([
    for(var i = 0;i < data.length;i++) {
      $http.get("http://example.com/" + data[i])
        .then(function (response) {
          $scope.data= response.data;
        })
        .catch(function (response) {
          console.error('dataerror', response.status, response.data);
          break;
        })
        .finally(function () {
          console.log("finally finished data");
        });
    }
  ]).
  then(function (results) {
    /* your logic here */
  });
};

This article is pretty good as well: http://chariotsolutions.com/blog/post/angularjs-corner-using-promises-q-handle-asynchronous-calls/

like image 7
Enkode Avatar answered Oct 29 '22 00:10

Enkode