Ensure $q.all does not produce an error when one promise is not resolved

While geocoding addresses, there are instances where some fail. My goal is to retrieve the successful results and disregard the failed ones in order to display the coordinates on a map. Currently, using $q.all triggers the errorHandler when one promise is rejected, causing me to lose the results of other promises.


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

Answer №1

Interrobang proposed a solution that is effective, although it does come with a bug. If you prefer not to have decorators impact every promise in your code, an alternative approach similar to allSettled can be implemented:

var handleRejection = function(promise) { return promise.catch(function(){}); } 
$q.all(promises.map(handleRejection)).then(function(results) {
     for (var k = 0; k < results.length ; k+=1) {
          //results[k] contains the data on success or is undefined on failure
      }
});

Answer №2

If you're looking for a way to handle all promises being settled at once, consider using q.allSettled. Unfortunately, this feature is not currently implemented in Angular.

You can voice your support for implementing this feature by commenting on this GitHub issue.

In the meantime, you could try incorporating a custom implementation like this one named allComplete into your Angular application:

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;
    }]);
  })
;

Answer №3

To solve the issue using Angular implementation, you can isolate async calls in a separate function that returns a promise, which will be managed automatically.

For example, if you have multiple async calls with authorization checks and want to handle failures gracefully, you can create a function like getCatalogPromise to manage the promises:

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;
    });
}

The key is to always resolve the promise in getCatalogPromise, regardless of the service response. This ensures that $q.all behaves as expected, allowing you to handle failure cases gracefully by returning an empty array.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

converting the names of files in a specific directory to a JavaScript array

Currently working on a local HTML document and trying to navigate through a folder, gathering all the file names and storing them in a JavaScript array Let's say I have a folder named Videos with files like: - VideoA.mp4 - VideoB.mp4 How can I cre ...

Using JQuery to delete an item by clicking on the delete button and then clicking on the item to remove it

I am currently using jQuery to dynamically create items on an HTML canvas for users to drag around and create drawings in a style similar to Microsoft Visio. However, I am struggling with how to remove these items once they have been created. While I know ...

Understanding AngularJS: Exploring Directives and Scope

Below is the code, my expectation is to see parent: true once I click the toggle button Unfortunately, it's not working as expected For reference, here is the link to plunker <body ng-controller="MainCtrl"> <button type="button" ng- ...

I am interested in checking the dates of the current date and disabling the button if the date falls within that range

I am attempting to deactivate a button if the current date falls within a three-month period. Despite my efforts to use a combination of Php and JavaScript, I was unable to make it work. PHP Code @php($found = false) @foreach($doctors as $doctor) ...

Focus event in IE does not always work as expected after an ajax request is

Our current focus is on supporting IE8 exclusively. An ajax call retrieves data from the server, replaces the HTML in a container div with the response, and then attempts to focus on an element within the response. However, there seems to be inconsistenci ...

Having trouble with executing functions on an express js Route?

I'm currently exploring Node and Express, and I'm encountering an issue when trying to pass a function instead of plain text on my route. It seems that the documentation only mentions using res.send() method with text. Even when attempting to use ...

The implementation of pushing inside a foreach loop is not correctly adding elements to

I have encountered an issue with running a foreach loop and adding values to an array in my code. The first foreach loop works as expected, adding values properly to the array. However, the second foreach loop seems to be malfunctioning as none of its valu ...

Adjust the tally of search results and modify the selection depending on the frequency of the user's searches within an array of objects

Seeking assistance with adding a new function that allows users to navigate to the next searched result. Big thanks to @ggorlen for aiding in the recursive search. https://i.stack.imgur.com/OsZOh.png I have a recursive search method that marks the first ...

How can I identify the blur or focusout event in a tinyMCE textarea?

I have been tackling with an existing project. Whenever I click on some editable text within the webpage, it transforms into a textarea and shows the tinyMCE toolbar. However, when I click outside of that textarea, the toolbar disappears. I am trying to fi ...

Is it possible for me to utilize window.top within the .js file?

Within my GWT code, I am transferring a variable to a JSP file. The process looks like this: <html> <head> <script type="text/javascript"> alert("Inside the JSP file"); var criticalPath = window.top.criticalPath; ...

Inaccurate data saved to a cookie

I attempted to assign a string from PHP to a cookie and retrieve the value of that cookie using JavaScript. Take a look at my code snippet: <php $date=date('Y',time()); //assume it is 2017 setcookie("Year", $date, time() + 3600, "/"); ?> ...

Detect Flash Player Event using Javascript

Is there a way to detect when a flash video ends without depending on user input like clicking the stop button? It's important to note: I HAVE NO CONTROL OVER THE PRESENTATIONS OR SWF FILES. My goal is to automate the client player object through s ...

Encountering a Uncaught TypeError when attempting to split an undefined property, but issue is limited to certain pages

Recently, I've encountered an issue with iziModal on specific pages where I'm getting an error message. The error I'm facing is: Uncaught TypeError: Cannot read property 'split' of undefined at r.fn.init.t.fn.(anonymous fu ...

What are some methods for controlling a webpage? Is it through HTML, JavaScript, Xpath, or

Hey there, I could really use your expertise on untangling a question that has me completely stumped. What exactly is the mechanism for controlling a webpage? a. HTML b. JavaScript c. Xpath d. CSS ...

Executing Code Upon Module Load and Presenting It as Middleware

I am currently delving into the intricacies of how exporting and importing modules function in Nodejs. One of my tasks involves using a specific file to seed a mongodb database. Surprisingly, this file operates flawlessly and delivers the desired results ...

Using Passport.js with client-side templating: A step-by-step guide

I've been using passport js for authentication, but I'm also implementing the angular $route service for client-side templating. This dual approach has left me uncertain about how to effectively utilize passport, especially since most of the exam ...

Tips for submitting a form using javascript while preventing the default action

Looking for a way to submit a form in Javascript and prevent the default action? Let's explore how you can achieve this. Initially, my HTML form with the ID "contact_form" had an input element like so: <input id="contact_send_msg" type="submit" val ...

Achieve Custom Styling in Material UI Stepper Label with ReactJS: Adjust Font Size and Margin Top

Is there a way to adjust the fontsize of the stepper label and the margin between the label and circle? The default marginTop is set to 16px, but I would like to reduce it. Any suggestions on how to achieve this? Check out the Codesandbox code using Mater ...

Understanding the functionality of scope in AngularJS is essential for mastering the framework

Why does this code work? app.controller("ctrl", function($scope){ $scope.From = "Santa"; $scope.To = "Claus"; }); And why doesn't this one work? app.controller("ctrl", function(scope){ scope.From = "Santa"; scope.To = "Claus"; }); ...

Utilizing Observable Data in Angular 4 TypeScript Components

Looking to extract and assign a JSON value obtained from an API into a variable. Here is an example: TS this.graphicService.getDatas().subscribe(datas => { this.datas = datas; console.log(datas); }); test = this.datas[0].subdimensions[0].entr ...