0

I need to call the function after 2 request is done. So I try to use $q.all for this. I have service on Angular it calls submitForm, before submit I need to do 2 another request, and after they response - make post request to submit form. It looks like this:

    submitForm : function(form, params) {
     var self = this;
     var callback = function () {
      // this is submit post req
     };

     angular.forEach(form, function(item) {
      // I search tables (type of field) and then send req for saving tables on backend
      self.uploadTables(item)
     })

     this.uploadFiles(params).then(callback)

    }
    uploadFiles : function(params) {
     // this func upload files before submit
    }
    uploadTables : function(params) {
     // for uploading tables I have another service on backend, so I need another request, before submit
    } 

In $q.all I guess I need to call it like $q.all(this.uploadFiles, this.uploadTables)? But I cant do that couse uploadTables I call in forEach. How can I call callback function after complete uploadFiles and uploadTables?

YoroDiallo
  • 345
  • 3
  • 6
  • 26

2 Answers2

3
var promises = [];
angular.forEach(form, function(item) {
      promises.push(self.uploadTables(item).then(uploadTableCallback));
})
promises(this.uploadFiles(params).then(uploadFilesCallback));
$q.all(promises).then(allCallback)

I want also to notice that there is nothing special in $q.all and you can always do it manually:

var promisesToResolve = arr.length;
var promisesResolve = 0;
    angular.forEach(arr, function(obj) {
          $http.post(obj).then(function() {
              promisesResolve++;
              if (promisesResolve == promisesToResolve) {
                  // all resolved
              }
          })
    })
Petr Averyanov
  • 9,327
  • 3
  • 20
  • 38
  • 1
    Your implementation of $q.all is wrong, namely if one of the promises rejects it hangs forever. It also doesn't collect the results. – Benjamin Gruenbaum Nov 25 '16 at 12:49
  • More like `arr.reduce((p, c) => p.then(v => c), $q.resolve())` and to collect the results uglily `const results = []; arr.reduce((p, c) => p.then(v => results.push(v), c), $q.resolve()).then(() => results)` – Benjamin Gruenbaum Nov 25 '16 at 12:51
  • @Benjamin Gruenbaum perhaps I need to handle rejects from $q to resolve "hangs forever"? couse this is works for me – YoroDiallo Nov 25 '16 at 13:42
  • @Banjamin, I am not telling that some1 need to use my implentation. (Btw it works ok if something is rejected - callback wont be executed) Why write something if it is already exist in angular? Just want to demonstrate that all this is quite simple. – Petr Averyanov Nov 25 '16 at 14:59
-1

You can return and collect promises in array

var promises = [];


angular.forEach(form, function(item) {

    var deferred = $q.defer();
    //do your code
    deferred.resolve(result);

    promises.push(deferred.promise);
});

// execute all the promises and do something with the results
$q.all(promises).then(

    function(results) {
      //do your stuff
    },
    // error
    function(response) {
    }
);
Disha
  • 822
  • 1
  • 10
  • 39