Coordinating Multiple Angular $http Requests using $q and Managing Errors with $q.catch

Struggling with understanding the correct utilization of Angular's $q and JavaScript's promise API. As a newcomer to Javascript, it's possible I'm making a syntax error.

This question appears similar, but isn't an exact duplicate...

The method in my service (called by the controller) looks like this:

self.getResources = function() {

    let promises = [];

    for (let resourceName in $rootScope.resourceNameList) {

        promises.push($http({ 
            url : '/' + resourceName,
            method : 'GET' 
        }).then(function (res) { 
            return { resourceName : res.data};
        }));
    }
    return promises;
};

The controller passes the promise list returned into Angular's $q.all():

let promises = resourceService.getResources();

$q.all(promises).then(function (resultsArray) {

    // resultsArray should be an array of elements like:
    // [ {cars : [...]}, {coffeePots : [...]}, {motorBoats : [...]} ]
    // with size = resourceNameList.length(), correct? 

    // this log is never called.
    console.log(resultsArray);
    $scope.resources = resultsArray;
});

Finally, in the HTML code, I attempt to loop through and display the resources:

.
.
.
<!-- 'cars' is an example, but I am trying to retrieve this data in the same way -->
<tr ng-repeat="item in resources[cars]">
    <td>{{item.property1}}</td>
    <td>{{item.property2}}</td>
</tr>

No results are showing up in the table.

Despite successful HTTP requests that return data visible in the console, there seems to be a mistake with either the promise or $q APIs.

Any recommendations?

Thank you!

Answer №1

It seems like you have already discovered a mistake in your input data, but it's important to detect these issues early on by implementing a .catch on your root promise. This way, you can quickly identify any problems that arise.

Here is an example of how you can modify your root promise to include a catch block for error handling:

let promises = resourceService.getResources();

$q
 .all(promises)
 .then(function (resultsArray) {
   console.log(resultsArray);
   $scope.resources = resultsArray;
 })
 .catch(function (error) {
    // Handle the error here by logging it or taking appropriate action
    window.open("https://stackoverflow.com/search?q="+error.message);
 })
 ;

If you need to filter out failed promises when using $q.all, consider using $q.allSettled instead. You can find more information about the full API here.

Additionally, if you feel limited by the capabilities of $q and want features like combining .push or .map with

.all</code, you can explore using <a href="http://bluebirdjs.com" rel="nofollow">BluebirdJS</a> along with this <a href="https://github.com/mattlewis92/angular-bluebird-promises" rel="nofollow">angular wrapper</a> for enhanced functionality.</p>

<p>Take a look at this updated code snippet using BluebirdJS:</p>

<pre><code>Promise.map($rootScope.resourceNameList, function(resourceName) {
      return $http({ 
        url : '/' + resourceName,
        method : 'GET' 
      });
}, {concurrency: 3})
.then(function(results) {
  console.log(results); // Successfully resolved promises
},function(rejects) {
  console.log(rejects); // Rejected promises
})
.catch(function (error) {
    // Handle errors appropriately
    window.open("https://stackoverflow.com/search?q="+error.message);
})
;

By making these adjustments, you can improve error handling and enhance the efficiency of your code. Happy coding!

For more insights on promises, check out this informative read:

Answer №2

To properly utilize the directive, ensure to include $q and $http within it in the following manner:

self.fetchData = function($q,$http) {

let dataPromises = [];

for (let dataName in $rootScope.dataList) {

    dataPromises.push($http({ 
        url : '/' + dataName,
        method : 'GET' 
    }).then(function (response) { 
        return { dataName : response.data};
    }));
}
return dataPromises;

};

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

What criteria should I consider when selecting a make for the createTheme components?

After reviewing the documentation for the createTheme component, I noticed examples with MuiButtonBase, MuiButton, and MuiSlider. However, when it comes to adding a button, it's simply called Button, not MuiButton. So, does this mean I just need to p ...

A guide on smoothly navigating to the desired row in a gridview using Asp.net

Currently, I am developing a project using ASP.net and C# technology. In my application, I integrated a GridView that contains multiple rows. Within the grid, there is a text box and a search button available. The columns displayed in the grid are Id and ...

Comparing DOM Creation in PHP and JavaScript

My website currently does not have any ajax requests, and here is a simplified version of my code: class all_posts { public function index($id){ $statement = $db->prepare("SELECT * FROM mytable WHERE id = :id"); $statement->exe ...

Review a roster of websites every half a minute (Revise pages every half an hour??)

Just starting out with HTML coding! Can someone please provide the code that will allow me to save various webpages and automatically cycle through them every 30 seconds? And also ensure that the webpages are updated every 30 minutes. ...

The AngularJS model fails to refresh after using $state.go function

My login system is almost complete, but I am facing an issue where the model does not update automatically after a successful login. The user should be redirected to the dashboard page once they log in. Currently, everything works fine except that the mode ...

Enabling communication between two single file components

Is there a way for two single file components to communicate with each other? Consider this scenario: I have two components, Content.vue and Aside.vue I want to be able to trigger an update in the Content.vue component when a button inside Aside.vue is c ...

Creating interactive content using AngularJS

Recently delving into the world of AngularJS, I find myself in need of some assistance! I'm currently working on a Widget Container that allows users to add pre-defined widgets to the container. Each widget comes with its own set of behaviors, hence ...

Aggregating multiple parameters in a D3 Treemap visualization

I have come across an interesting challenge while working on a project involving a zoomable treemap. I am currently exploring how to pass and aggregate multiple parameters within the treemap, similar to what is typically done in a zoomable treemap visualiz ...

AngularJS tips for resolving an issue when trying to add duplicates of a string to an array

Currently dealing with a bug that occurs when attempting to push the same string into an array that has already been added. The app becomes stuck and prevents the addition of another string. How can I prevent the repeat from causing the app to get stuck w ...

Showing all elements on page load that are currently being filtered out in React

I've created a page that displays a grid of images with various details like title, description, author, and more. All this data is being pulled from my SQL table (referred to as marketplaceData). To enhance user experience, I added a search bar to f ...

Transferring API requests from the controller to the service for more efficient processing

I have delegated the call to the Twitter API from my controller to a service: angular.module('main') .service('Tweet', function ($log, $http, Config, $ionicLoading) { this.display = function () { $ionicLoading.show({ ...

Using val() on a checkbox will give you an element, not a string literal

How can I retrieve only the literal values of all checked checkboxes without any additional data? My current approach is: $('input:checked').map(function() { return $(this).val(); }) The result that I am getting looks like this: e.fn.init[1]0 ...

Protractor encounters ElementNotVisibleError on Continuous Integration Server

While my angular end-to-end tests with Protractor and Cucumber run smoothly on my local machine, I encounter an error when running them on the build server. Error: ElementNotVisibleError - element not visible Session info: chrome=51.0.2704.84 Driver inf ...

Assigning the Style property to an element using a string that includes HTML tags

My HTML string is populated with elements such as button, li, span, and more. I am looking to add specific styles to buttons based on their class name. For example, if button.btn { some styles } and button.btn-success { some other styles } O ...

Connect various models together, or create synchronized computed properties

At times, the model abstraction may fall short, leading to the necessity of synchronizing two different models. For instance, I have two lists linked by an angular sortable, which requires a model structure like this: left = [{name:"one"}, {name:"two"}]; ...

Having trouble accessing information from Firebase Realtime Database within a React Native application

I am currently developing a React Native application that interacts with a Firebase database for reading and writing data. I have configured my Firebase permissions to allow read and write access: { "rules": { ".read": true, ...

Switch the design and save it in the browser's cache

Exploring the possibility of having two themes, "dark" and "light," that toggle when a checkbox is clicked. To implement the theme change, I used the following JavaScript code: document.documentElement.setAttribute('data-theme', 'dark&apos ...

JavaScript linking in HTML anchor tag

Can someone please assist me in getting this code to function properly? I am having difficulty with the numerous quotation marks and unsure of where to place them correctly. Any guidance on resolving this issue would be greatly appreciated. <script typ ...

JavaScript utilized to create a fully immersive full-screen webpage

I have been trying to implement a code for creating a full-screen website that works on all browsers. Unfortunately, my current code only seems to be functioning properly on Mozilla browser. When I try to view the site in Chrome and make it full screen, it ...

Reveal each element individually upon clicking the button

I am trying to display 5 div elements one by one when clicking a button, but the current code is not working. I am open to alternative solutions for achieving this. Additionally, I want to change the display property from none to flex in my div element. ...