Make $ q.all fail when one promise is rejected

I geocode some addresses, sometimes some of them fail. I would like to get the rest of the results and ignore the unsuccessful one in order to display other coordinates on the map. Currently, $ q.all will call errorHandler when it is rejected, so I am losing the results of other promises.

      $q.all(promises).then(function(coords) {
          for (var j = 0;j<coords.length;j+=1) {
              //success code
          }
      }, function(error) {
        console.log("Failed",error.type,error.message);
      });
+4
source share
3 answers

You want q.allSettledone that is not implemented in Angular.

Here's the corresponding GitHub issue requesting its implementation.

, allComplete, Angular:

angular.module('App.services', ['ngResource'])
  .config( function($provide) {
    $provide.decorator("$q", ["$delegate", function($delegate) {
      var $q = $delegate;

      $q.allComplete = function(promises) {

        if(!angular.isArray(promises)) {
          throw Error("$q.allComplete only accepts an array.");
        }

        var deferred = $q.defer();
        var passed = 0;
        var failed = 0;
        var responses = [];

        angular.forEach(promises, function (promise, index) {
          promise
            .then( function(result) {
              console.info('done', result);
              passed++;
              responses.push(result);
            })
            .catch( function(result) {
              console.error('err', result);
              failed++;
              responses.push(result);
            })
            .finally( function() {
              if((passed + failed) == promises.length) {
                console.log("COMPLETE: " + "passed = " + passed + ", failed = " + failed);

                if(failed > 0) {
                  deferred.reject(responses);
                } else {
                  deferred.resolve(responses);
                }
              }
            })
          ;
        });

        return deferred.promise;

      };

      return $q;
    }]);
  })
;
0

, Interrobang, ( ), , , - allSettled, :

var suppress = function(x) { return x.catch(function(){}); } 
$q.all(promises.map(suppress)).then(function(coords) {
     for (var j = 0; j < coords.length ; j+=1) {
          //coords[j] contains the coords on success or is undefined on failure
      }
});
+9

, Angular, , , , .

, , , , , .

  function getAllCatalogs() {
        return $q.all([
            $http.get(baseUrl + 'equipment-design/'),
            $http.get(baseUrl + 'engines-design/'),
            $http.get(baseUrl + 'suspension-design/'),
            $http.get(baseUrl + 'artifacts-design/')
        ]).then(function (data) {
            return data;
        });
    }

- $q.all , promises , - , , , , , , fail , , , , $http.get , getCatalogPromise, URL- , :

   function getCatalogPromise(url) {
        var deferred = $q.defer();

        $http.get(url).then(function (response) {
            deferred.resolve(response)
        }, function () {
            deferred.resolve([]);
        })

        return deferred.promise;
    }

    function getAllCatalogs() {

        return $q.all([
            getCatalogPromise(baseUrl + 'equipment-design/'),
            getCatalogPromise(baseUrl + 'engines-design/'),
            getCatalogPromise(baseUrl + 'suspension-design/'),
            getCatalogPromise(baseUrl + 'artifacts-design/')
        ]).then(function (data) {
            return data;
        });
    }

if you pay attention to the getCatalogPromise code , it doesn’t matter what returns the service call, which our deferred will always be in a permission state, and this is what $ q.all , the only difference is that if the service fails, we return empty array.

0
source

All Articles