shankys
shankys

Reputation: 77

chained angularjs $http requests within for each loop

I need to check when the "for loop" function has finished for all $http requests processing and can refresh the data grid, once and for all. Currently, the refresh happens for every $http request, which is not desired behaviour.

Have read a little about angularjs $q.all, but not sure of implementation in the scenario below.

Any help / advise is greatly appreciated. Thanks in advance.

Here is the snippet -

function chainedAjax(param1, param2) {
  var something = something;
  $http({
    // processing
  }).then(function(responseData) {
    // processing 
    return $http({
      // processing
    });
  }, function(ex) {
    // error
  }).then(function(responseData) {
    // processing
    return $http({
      // processing
    });
  }, function(ex) {
    // error       
  }).then(function(responseData) {
    // success - Done
    finish();
  }, function(ex) {
    // error
  });
}

function init(selectedDocs) {
  var something = something;
  angular.forEach(selectedDocs, function(item, arrayIndex) {
    chainedAjax(item.param1, item.param2);
  });
}

function finish() {
  refreshDocsTable(); // refreshes the current grid
}

init(selectedItems); // call init function

Upvotes: 0

Views: 569

Answers (2)

sb.olofsson
sb.olofsson

Reputation: 919

The code is a little bit vague to give a good answer, but I assume that your outer $http-call in the chainedAjax-function is the one that you want to detect when has executed x times. There seems to be some inner $http-calls as well, and I assume that these are the ones, you want to get rid of. You could do something likes this:

function chainedAjax(param1, param2) {
  var something = something;
  return $http({
    // processing
  }).then(function(responseData) {
    // processing 

  }, function(ex) {
    // error
  }).then(function(responseData) {
    // processing

  }, function(ex) {
    // error       
  }).then(function(responseData) {
    // success - Done
    finish();
  }, function(ex) {
    // error
  });
}

function init(selectedDocs) {
  var something = something;
  var count = 0, target = selectedDocs.length - 1;
  angular.forEach(selectedDocs, function(item, arrayIndex) {
    chainedAjax(item.param1, item.param2).then(function(){
        count++;
        if(count == target){
            // All requests are done
            // Now make one final call to update datatable
            $http({
                // parameters
            }).then(function(response){

            });
        }
    }).catch(function(err){
        // A single http request failed, if you want to count that as well, uncomment the line below
        // count++;
    });
  });
}

Since $http already returns a promise, you don't need to use $q to get signaled when the requests are done. Let me know if the answer points you in the right direction.

Upvotes: 0

Marcelo
Marcelo

Reputation: 4608

You need something like this, assuming you actually need multiple requests for each item:

function chainedAjax(param1, param2) {
  var something = something;
  return $http({})
    .then(function(responseData) {
      // processing 
      return $http({});
    })
    .then(function(responseData) {
      // processing
      return $http({});
    })
}

function dealWithError(error) {}

function init(selectedDocs) {
  var something = something;
  var requests = [];
  angular.forEach(selectedDocs, function(item) {
    requests.push(chainedAjax(item.param1, item.param2));
  });
  $q.all(requests)
    .then(finish)
    .catch(dealWithError);
}

Upvotes: 2

Related Questions