What is the reason behind child state resolve functions being executed prior to the parent state promises being resolved?

I am currently utilizing ui-router version 0.2.13. According to this page:

All resolves on one state will be resolved before moving on to the next state, even if they aren't injected into that child

Additionally, all resolves for all the states being entered are triggered and resolved before the transition will enter any states (regardless of the resolve being injected somewhere)

However, in my particular scenario, the resolve function for the child state is being executed before the resolve promise for the parent is resolved. How can this be happening?

Take a look at the code below:

$stateProvider
    .state('route1', {
        url: "/route1",
        templateUrl: "route1.html",
        resolve: {
            parent: ["$timeout", "$q", function ($timeout, $q) {
                var d = $q.defer();
                $timeout(function () {
                    d.resolve();
                }, 5000);
                return d.promise;
            }]
        }
    })
    .state('route1.list', {
        url: "/list",
        templateUrl: "route1.list.html",
        controller: function ($scope) {
            $scope.items = ["A", "List", "Of", "Items"];
        },
        resolve: {
            child: function () {
                alert("I'm shown before `parent` resolved");
            }
        }
    });

When navigating to /route1/list, the alert message is displayed immediately without waiting for the parent resolve promise to be resolved after 5 seconds.

Answer №1

It is guaranteed that all resolves will be completed before the transition occurs. However, it should be noted that the resolve functions are not called synchronously, which is the correct behavior.

Based on the ui-router source code, invocables are resolved in a "parallel" manner whenever possible. Only those dependent on other invocables, either from parent states or the current state declaration, will be executed after their dependencies are resolved.

Therefore, to ensure that the child invocable is only called after the parent is resolved, you must specify parent as a dependency of the child invocable.

.state("route1",{
   //..
   resolve: {
        parent: ["$timeout", "$q", function ($timeout, $q) {
            var d = $q.defer();
            $timeout(function () {
                d.resolve();
            }, 5000);
            return d.promise;
        }]
    }
 })
 .state("route1.list",{
    //...
    resolve: {
         child: ["parent", function(parent) {
             //will be called only after parent is resolved
         }]
 })

The GitHub resolve.js source code comments explain:

Invocables are invoked eagerly as soon as all dependencies are available. This is true even for dependencies inherited from a parent call to $resolve.

Answer №2

Understanding the concept of injecting "parent" into child routes is crucial for proper resolution order. Without this injection, the parent may not wait for resolution before the child. Consider the following code snippet:

resolve: {
  child: function(parent) {
    alert("Child Resolved!");
  }
}

Here, the child's resolution will occur after the parent's timeout.

The documentation likely emphasizes waiting for all resolutions to complete before transitioning to a state, including loading controllers and rendering templates.

In the provided Plunker demo (adapted from an old scotch.io example), the dependencies were rearranged to illustrate resolution order. If the child resolve is dependent on a parent resolve, the parent resolves first. On the other hand, if the child does not have a dependency, it resolves first, regardless of the timeout length being set to 0.

Regardless of the scenario, both parent and child controllers remain untouched until both parent and child resolutions are complete.

http://plnkr.co/edit/EtU03AfgUAlWNsEH0TuU?p=preview

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 sets $(document).on apart from ($ document).on in CoffeeScript?

One of my buddies is incorporating ($ document).on into his CoffeeScript script. I'm curious to know if this differs from the typical $(document).on and, if it does, how so? ...

Communication between clients using a Progressive Web Application (PWA) when

Is there an efficient way to communicate and share data between devices using an offline progressive web app without internet access? I thought of exploring the possibilities with the Web Bluetooth API and generating QR codes through libraries like QRCode ...

Guide on using JavaScript to implement the universal CSS selector

One technique I frequently employ is using the CSS universal selector to reset the dimensions in my HTML document: * { border: 0; margin: 0; padding: 0; } I wonder if a similar approach can be achieved with JavaScript as well? When it come ...

Use jQuery to update the field without affecting the observable

Greetings to the wonderful stackoverflow community! I recently delved into using knockout just a few days back. Currently, I am utilizing it to create a dynamic menu builder for a CMS project that I'm deeply engrossed in. If you'd like to take ...

The XML information vanished during the transformation into JSON format

After converting XML to JSON using multiple conversion libraries, I noticed that the property name attributes and Item name attributes were lost. Why is this happening? Does anyone have suggestions on how I can modify my XML to make it more compatible for ...

Having difficulty setting up multiple buttons to share the same function in jQuery using HTML

After clicking a button, my code dynamically adds content to a div and inserts buttons with names like "teamReq_"+index+"_AddYear" into the document (where index is a number retrieved from a hidden input field). If these buttons are spammed, multiple divs ...

HTTP GET request not updating data

I'm experimenting with AngularJS and trying out some examples: Here's the HTML code snippet: <html ng-app="myApp"> <body ng-controller="JokesController"> <h1>{{ joke }}<h1> </body> </html> A ...

Is it possible to use multiple routes in the same page with Vue-router?

In the process of developing a Vue-based web application that utilizes vue-router in history mode, everything was functioning smoothly for navigating between various pages. However, a new request has been made to open certain pages within a virtual dialogu ...

Manipulate a JSON object with JavaScript

Struggling to find a solution on my own. In my hidden field, I have some JSON data stored. To retrieve this data, I'm using the following syntax: $(document).ready(function() { var data = $("#result").text(); var j = JSON.parse(data); j.my_item.to ...

Tips for creating an illustration in Vue.js

As I attempt to create an image using canvas, my browser throws this error at me: Uncaught TypeError: Cannot read property 'drawImage' of undefined at Image.img.onload (test.js:23) To troubleshoot, I added some console.log() messages and here ...

Unable to modify variable values in AngularJS

I'm currently utilizing AngularJS along with the "Angular Material" implementation (found here: https://material.angularjs.org/latest/#/) One of the components I'm using is the SideNav component: https://material.angularjs.org/latest/#/demo/mate ...

Enhance your Wordpress posts with a custom pop-up form for each individual button

On a page, there are various custom posts being displayed with the post type 'property', each containing a button: <button class="btn btn-primary">Submit Offer</button> This button is looped and shown below every post. What ...

Selecting a "non-operational" collection location on an e-commerce platform

Recently I discovered a bug on an online shopping website. It seems that by using inspect element, it was possible to alter the HTML code and change an unavailable pickup point to available. This allowed me to place an order, make a payment, and even recei ...

Error occurring when attempting to pass messages within an iframe on a sandboxed page in a Chrome extension

Whenever I try to utilize my popup page for a chromium extension as a conduit for communication between the background page and a page shown within an iframe on the popup, I encounter the following error. I required a sandboxed environment to execute Vue.j ...

What is the proper way to include onMouseOver and onMouseEnter events in a reactjs project

Seeking assistance with implementing the onMouseOver event in React, but encountering issues. I have followed the correct procedures for using, calling, and setting State. Please review my code and provide guidance. import React from 'react'; c ...

Tips for displaying dynamic content in VueJS?

I'm currently working on an app that allows users to choose which type of vuetify element they want to display on the page. There are 4 options available for selection. My goal is to render the corresponding vuetify component when a user clicks on the ...

Optimizing Angular performance when working with tabular data

I am in the process of developing a new single page web application that will have a complex main view. I am currently debating whether to implement Angular.js and my main concern is the potential performance issues due to excessive data-binding. The main ...

Swapping out one variable for another

After tweaking my code a bit, I'm still struggling to get it right. User input: !change Hi var A = "Hello" if (msg.content.includes ('!change')) { A = msg.content.replace('!change ', ''); } msg.send(A); //the change ...

executing ajax request to call a function, encountering partial success and encountering partial failure

Apologies for the lack of clarity in the title. I currently have a search engine that utilizes an ajax function. At present, when I type "t" in the search box, only the tags containing the word "t" are displayed (for example, if I type "t", then "test" sho ...

Attempting to create a Next.js 13 application, but struggling with using the client-side functionality

Exploring Next.js for the first time, I embarked on creating a simple application. Everything was going smoothly until I attempted to include a "use client" tag at the beginning of a component to utilize certain hooks. This resulted in the app breaking and ...