What are the best practices for linking promises in a intricate sequence of resource loading?

When working with Angular code, I have a series of chained promises that look like this:

// Defined function in the LoaderService module.
var ensureTypesLoaded = function(){
   return loadContainerTypes($scope).then(loadSampleTypes($scope)).then(loadProjectList($scope)).then(loadSubjectTypes($scope));
}

Each of these functions returns a promise that loads data from a resource and also modifies the `$scope` on success or error, for example:

var loadProjectList = function ($scope) {

            // Calls getAll method within ProjectService and returns a promise.
            return ProjectService.getAll().then(
                function (items) {
                    // Successful load
                    console.log("Promise 1 resolved");
                    $scope.projectList = items; 
                }, function () {
                    // Error occurred
                    CommonService.setStatus($scope, 'Error!');
                });
        };

I plan to use it in controller initialization code as follows:

// In the controller's initialization code
LoaderService.ensureTypesLoaded($scope).then(function () {
            // Perform action when all promises are successful
             console.log("I will do something here after all promises resolve");
            }, function () {
            // Handle errors
            });

However, the timing is not as expected. The message "I will do something here after all promises resolve" appears before the messages indicating resolved promises within the functions listed in `ensureTypesLoaded`.

I am looking to create a function `ensureTypesLoaded` that:

  • Returns a promise that resolves only when all internal promises are resolved
  • If any of the internal promises fail, the function should stop and return a rejected promise
  • And most importantly, any actions specified in `then()` after calling `ensureTypesLoaded()` should be executed only after everything inside `ensureTypesLoaded` has been resolved

I need help in correctly structuring the chained promises. Thank you!

Answer №1

It seems like the issue lies within your loadProjectList function. The .then() method should receive a function that is called at resolution time, usually a function returning a chained promise.

In this case, you are calling all loads immediately in parallel, which can be a bit complicated with $scope passing. I believe your code should be structured like this:

//this function is called immediately upon creating the chain
var loadProjectList = function ($scope) {  
     //this function is called when the previous promise resolves
     return function(data) {
          //do not include error handling here
          ProjectService.getAll().then(...)
     }
}

This will result in serial loading as intended. (Just a note: for parallel execution done correctly, $q.all should be used)

Lastly, you should only have an error handler in ensureTypesLoaded, not in each individual promise.

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

My jQuery form is not functioning properly upon initialization

Let's take a look at this sample 'template' code: $(document).on("<EVENT>", "form", function() { $(this).find(".input input").each(function() { var required = $(this).attr("required"); var checkField = $(this).clos ...

Prevent the Icon in Material UI from simultaneously changing

I'm working on a table where clicking one icon changes all icons in the list to a different icon. However, I want to prevent them from changing simultaneously. Any suggestions on how to tackle this issue? Code: import React from 'react'; im ...

Discovering the precise date format within highcharts

I've been searching for a while now, but I still haven't found the perfect solution to this issue: The date highlighted in the red box in the image needs to adjust based on the user's country location. For example: For users in the US -> ...

Creating a network of lists by combining multiple arrays

I'm currently working on generating a comprehensive list of all possible combinations of multiple arrays. While I have experience in Matlab and understand loops and basic coding principles, I'm unsure of the most efficient method to compile these ...

Vue users are experiencing issues with the functionality of the Chart js plugin annotation

I've been attempting to include a horizontal line in my Chart.js using the annotations plugin, but it's not cooperating. My Chart.js version is 2.9.4, so I had to install it with the command: npm install [email protected] --save After inst ...

Is it possible to modify the color of a span element within a select dropdown?

Is there a way to change the color of a span to red within a select option in js fiddle? I am trying to modify the color of <span class="myError">This is a required field.</span> to red https://i.sstatic.net/nRF2c.png select{ color: green; ...

Using JavaScript regex to extract the text within a string

I have a specific string that needs to be extracted let str="[a54hy 8:45pm],[f57gh 9:20]" I am looking to retrieve [f57gh 9:20pm] Splitting the string is not an option due to its varying length ...

What occurs when a JavaScript variable is assigned a nonexistent variable?

When it comes to setting a javascript variable, I'm assigning it with a value as var newline = $("#newline").val(); It's important to note that the $("#newline").val() may or may not exist. Sometimes, the #newline may not be present in the DOM, ...

JavaScript events are failing to trigger within the content area of an iframe

When attempting to run a given example by double clicking inside the content area of an iframe, the clicks and any JavaScript events are not being fired. Currently, the events can only be triggered by clicking on the border of the iframe, not inside the ...

Incorporate Laravel data into Angular dropdown menu

Hello, I am utilizing Angular to populate a select box with options. I have fetched a list of tags that are structured as follows (encoded in JSON using Laravel for better readability); Effort options to be displayed in selection { "5. XS":{"94":"01:00: ...

What could be causing the issue with passing an ID through the href attribute of an anchor tag in

Greetings! I am working with a specific directory structure for my HTML files and have made adjustments to the .htaccess file to read .html files as .php when necessary. Snapshot 1: Directory structure https://i.sstatic.net/pHh67.png Snapshot 2: localho ...

Transforming PHP JSON into JavaScript with getJSON

Hello everyone, I must admit my lack of knowledge in javascript/ajax as I am struggling to convert this php json into a javascript function $json = file_get_contents('http://videoapi.my.mail.ru/videos/mail/alex.costantin/_myvideo/4375.json'); ...

Cannot find WoopraTracker within the custom event data

I am currently working on implementing Woopra custom event data upon page load by following their guidelines. I have attempted to push events when the page is ready, however, it keeps returning an error that woopratracker is not defined. Strangely, when ...

Leveraging async/await in express

I am encountering an issue with my app.post method while trying to deploy on Firebase. The error message reads: Parsing error: Unexpected token =>. I am fairly new to node.js and Javascript as I primarily work with Swift. However, I require this code fo ...

Ways to retrieve the specified data in Javascript in string format

I'm facing an issue where the data I passed from a JavaScript array to a Java servlet and back to JavaScript is showing as "undefined." Check out my JavaScript code below: var buildingNumbers = []; // Let's assume the values of buildingNumbers ...

Tips for successfully implementing an Ocrad.js example

I've been working on an OCR (optical character recognition) web application and stumbled upon the Ocrad.js JavaScript library Ocrad.js. It seems like a perfect fit for what I need, but unfortunately, I'm having trouble getting it to function prop ...

Issues with the functionality of the mouseover event when multiple objects are being overlaid

Seeking assistance with implementing mouseover tooltip effects on a d3 graph. The circle appears above the line, but the issue arises when the mouse hovers directly over the line causing the tooltip to disappear. Is there a way to prioritize the circle ove ...

Patience is key: techniques for real-time variable updates and calculations in JavaScript

Hi, I am currently working on creating a dashboard to calculate the total outstanding amount for my medicine suppliers using Next.js. Below is the code snippet for my "createPurchase" API: import PurchaseOrder from '../../models/PurchaseOrder' ...

Sending an ajax request to submit the results of jQuery.each loop

$(".submitinfo").each(function() { // Using ID as POST name and value as POST value }); // Sending the data using ajax request $.ajax({ url: 'submit.php', traditional: true, data: { 'submit':'true', 'age&a ...

Angular Grunt minification encountered an unexpected punctuation token «}», when it was expecting a colon punctuation «:»

Given that 'id' is a pre-defined dynamic variable, what could be causing it not to minify correctly? let dynamicVar = 'device_' + id; $scope[dynamicVar] = {dynamicVar}; This is the specific error message from grunt-contrib-uglify: ...