Sequencing the loading of resources in AngularJS one after the other by utilizing promises

While working in a service, my goal is to load a resource using $http, store it in a variable, load a child resource and store that as well. I understand the concept of promises for this task, but I am struggling with how to properly implement it in my code. Below is my current code snippet:

var project = {};
var todo = {};

function init(){
        var idProject = 21;
        var idTodo = 6;            

        // Check if idProject is provided
        if (idProject != null) {

            // Load project data first
            var promise = WorkspaceManager.getProject($rootScope.workspace, idProject);

            // Save project data after loading
            promise.then(function(response){
                project = response.data;                    
                return project;
            });

            if (idTodo != null) {
                // Then load todo data
                promise.then(function(project){   
                    return ProjectManager.getTodo(project, idTodo);
                });

                // Save todo data after loading
                promise.then(function(response){
                    todo = response.data;                    
                    return todo;
                });
            }       
        }

        console.log(project); // Output: {}
    }

init()

Any insights or guidance would be appreciated!

Answer №1

To correctly comprehend this scenario, it is evident that the task at hand is more complex than it initially seems. A function is required to synchronize two asynchronous processes and yield a promise containing a combined value from both processes.

There are two potential methods to tackle this:

  • Simplistic yet inelegant: Store the necessary values as properties of an external object in each asynchronous process.
  • Sophisticated but cumbersome: Accumulate the desired values as properties of an object within each asynchronous process, with a promise returned for accessing it.

The provided code exemplifies the first approach :

function init() {
    var idProject = 21;
    var idTodo = 6;
    var projectObj = {};//This object serves as a repository for asynchronously acquired data.
    if ( idProject != null ) {
        return WorkspaceManager.getProject($rootScope.workspace, idProject).then(function(response) {
            projectObj.project = response.data;//store `response.data` in the repository as .project.
            if( idTodo != null ) {
                return ProjectManager.getTodo(response.data, idTodo);
            }
        }).then(function(toDo) {
            projectObj.toDo = toDo;//store `toDo` in the repository as .toDo .
            return projectObj;
        });
    }
}

init().then(function(projectObj) {
    console.log(projectObj.project);
    console.log(projectObj.toDo);
});

Alternatively (still following the first approach) with error handlers :

function init() {
    var idProject = 21;
    var idTodo = 6;
    var projectObj = {};//This object serves as a repository for asynchronously acquired data.
    if ( idProject != null ) {
        return WorkspaceManager.getProject($rootScope.workspace, idProject).then(function(response) {
            projectObj.project = response.data;//store `response.data` in the repository as .project.
            if( idTodo != null ) {
                return ProjectManager.getTodo(response.data, idTodo);
            }
            else {
                $q.defer().reject('idTodo invalid');
            }
        }).then(function(toDo) {
            projectObj.toDo = toDo;//store `toDo` in the repository as .toDo .
            return projectObj;
        });
    }
    else {
        return $q.defer().reject('idProject invalid');
    }
}

init().then(function(projectObj) {
    console.log(projectObj.project);
    console.log(projectObj.toDo);
}, function(errorMessage) {
    console.log(errorMessage);
});

untested

Answer №2

You are currently creating a chain of promises based on the initial promise, forming a sequence of "brothers" promises. All these promises will be resolved once the WorkspaceManager.getProject promise is also resolved. It seems like what you actually want is to link them together so that when the first promise is resolved, you request Todo data, and upon receiving it, you proceed to save it. To achieve this, you should capture the resulting promise from each step.

// Save project data first
promise = promise.then(function(response){
  project = response.data;
  return project;
});

// Load todo data next
promise = promise.then(function(project){   
  return ProjectManager.getTodo(project, idTodo);
});

// Save todo data after loading
promise.then(function(response){
  todo = response.data;                    
  return todo;
});

To further clarify, the initial setup can be compared to:

var mainPromise = ...;
mainPromise.then(function loadTodo(mainPromiseReturn){});
mainPromise.then(function saveTodo(mainPromiseReturn){});

In this case, the operations of loading and saving todos run parallelly and independently, without being interconnected. They both operate on the same set of data.

The recommended approach would be more like:

var mainPromise = ...;
mainPromise
  .then(function loadTodo(mainPromiseReturn){})
  .then(function saveTodo(loadTodoReturn){});

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

Is JQuery function running on its own or triggered by an event without manual input?

When visitors come to my website, I want them to see two options: one for registration and the other for logging in. To achieve this, I've created two buttons and a function that makes the form/input fields fade in when clicked. However, the issue is ...

What is the process for integrating three.js code manually into an iframe?

I recently posted a question on Stack Overflow inquiring about how to input code into an iframe without using a file or URL. While I was successful with simple cases like <h1>Hello World</h1>, my ultimate goal is to integrate three.js into thes ...

Reaching out to the Edge: Enhancing the jQuery Slider Experience

Alright, I'm really excited about using this amazing slider. What I love most is the "free mode" feature that creates this stunning sliding effect. The size and number of slides are absolutely perfect for me. But there's just one small adjustment ...

Having trouble getting webpack and babel to start using npm

Greetings, wonderful people of the internet! I am a newcomer to the enchanting world of programming and I am facing a perplexing issue. Although Webpack is trying to guide me towards the solution, I seem to be struggling with fixing it on my own. const pa ...

Struggling with establishing recognition of a factory within an Angular controller

I am currently facing an issue while trying to transfer data from one controller to another using a factory in Angular Seed. My problem lies in the fact that my factory is not being recognized in the project. Below is my snippet from app.js where I declare ...

Converting a date from PHP to JavaScript

My PHP code generates the following date: <?php date_default_timezone_set('Europe/London'); echo date('D M d Y H:i:s O'); ?> Additionally, I have a JavaScript/jQuery script that displays this date on the website: setInterval( ...

The v-show directive is not activated by a Vuex commit

I am experimenting with vuex for the first time, and I have come across an issue where a v-show directive is not triggering after a mutation commit on the store. // store.js import Vue from "vue" import Vuex from "vuex" const states = ...

Numerous slideshows using identical scripts

I am facing an issue with my code for multiple slideshows. Currently, it works fine for a single slideshow but when I have multiple slideshows and mouse over any of them, all the slideshows start running due to sharing the same class. However, if I try to ...

Using the power of ReactJS, efficiently make an axios request in the

After familiarizing myself with Reactjs, I came across an interesting concept called componentDidUpdate(). This method is invoked immediately after updating occurs, but it is not called for the initial render. In one of my components, there's a metho ...

Issues with JQuery Ajax rendering in browser (suspected)

I'm encountering an issue on my webpage. I have a div with two hidden fields containing values of 0 and 2, respectively. Upon clicking a button that triggers an AJAX query, the div contents are updated with hidden field values of 1 and 2. However, it ...

The div swiftly clicks and moves beyond the screen with animated motion

Here is a code snippet that I am working with: $(document).ready(function(){ $(".subscriptions").click(function (){ if($(".pollSlider").css("margin-right") == "-200px"){ $('.pollSlider').animate({"margin-right": '+ ...

Using Sequelize to Create/Post Data with Many-to-Many Relationship

I've been exploring how to implement a M:N Association using Sequelize. After examining the documentation (doc), I came across a solution that closely matches my requirements: User.belongsToMany(Profile, { through: User_Profile }); Profile.belongsToMa ...

Is there a way to automatically close the InAppBrowser once certain content is displayed?

Is there a way to automatically close the $cordovaInAppBrowser when it loads my website and retrieves the content "OK"? My goal is to hide the close button in the browser window. Any suggestions on how to accomplish this? ...

What is the best way to deal with a "Access to restricted URI denied" error in JavaScript while utilizing XMLHttpRequest?

Here is some code I am working with: var req = new XMLHttpRequest(); req.onload = function(){ if (req.status === "200"){ doSomethingWithTheReceivedData(); } else { alert("Error msg"); } }; When running index.html directly ...

The Next.js Image component is not compatible with an external URL as the image source

I've been struggling to use the image component in Next.js with an external URL as the source, but I keep encountering an error. I followed the instructions in the official Next.js documentation and updated the next.config.js file, but unfortunately, ...

What is the best way to transform the pages extracted through the Notion API into slugs?

I'm new to Next.js and Notion API, and I want to create a blog site on my personal website using the Notion API. While I can easily pull the posts, I am facing a challenge in slugifying the endpoint IDs with post titles. When attempting this based on ...

What is the best way to save a jQuery or JavaScript variable into a JSON file?

Is there a way to save a jquery variable in a json file? I have the following: var image='/test/test.png'; I am obtaining this path through file upload: <input type="file" name="imageurl" value="imagefile"></input> Therefore, I ne ...

Watch for changes in a nested collection in Angular using $scope.$watch

Within my Angular application, there is a checkbox list that is dynamically generated using nested ng-repeat loops. Here is an example of the code: <div ng-repeat="type in boundaryPartners"> <div class="row"> <div class="col-xs- ...

Experiencing prolonged delays with PHP/AJAX login process

Recently, I took over the maintenance of a website that requires users to log in. However, I've noticed that the login process is quite slow, especially when there are around 4000 registered users. The current login system utilizes a combination of A ...

Is it possible to list bash/sh files as dependencies in package.json?

Currently, I have a bash script named publish.sh that I use for publishing modules to npm. Since I am constantly adjusting this script, I find myself needing to update every copy of it in each npm module I manage. Is there a method to include this bash sc ...