Angular - property value changes will not take effect until the output callback completes

When I have a component that needs to display a spinner during an operation, I came across an issue:

This is the HTML code snippet:

<spinner *ngIf='isLoading'></spinner>
<xx-table
  (onSort)='onSort()'>
</xx-table>

This is the TypeScript code of the component:

onSort(): void {
  this.isLoading = true;
  // The operation takes about 1 second
  this.isLoading = false;
}

Although I explicitly set this.isLoading to true, the change is not reflected in the template. It seems like the change detection is only triggered after the onSort() method finishes executing. If I remove the line this.isLoading = false;, the spinner shows up and remains there for approximately 1 second before disappearing.

How can I make sure this change is visible while the method is still running? And what exactly is the mechanism behind this behavior?

(I am aware that I can trigger change detection manually, but I'm curious why this change is not automatically detected.)

Answer №1

In the world of javascript, a block of code will tirelessly run until its mission is accomplished, following a single execution path diligently. It seems that your code operates synchronously without any asynchronous operations in sight, preventing angular from stepping in to update the page while isLoading holds true.

To overcome this hurdle, you have two options at your disposal. You can employ setTimeout to delay the execution of certain tasks by a specified number of milliseconds or immediately with '0' to allow the current execution path and pending events to be handled by the swift javascript runtime:

  embarkOnQuest(): void {
    this.isLoading = true  
    this.exploreMysteries() 
    this.isLoading = false 
  }
  
  embarkOnAsyncQuest(): void{
    this.isLoading = true
    setTimeout(() => { 
      this.exploreMysteries()
      this.isLoading = false
    }, 0)
  }

Answer №2

this.isDataLoading = false;

Make sure to place this line at the end of the promise or observable subscribe function. In your scenario, setting this.isDataLoading = true is immediately followed by setting it to false without waiting for the promise to finish.

// Function that takes around 1 second to complete

This is an asynchronous operation. Learn about handling promises and observables in JavaScript to grasp the concept better.

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 are the steps to break down a TypeScript interface and incorporate it into another interface?

Currently, I am experimenting with a typescript pattern and I'm uncertain if it can be implemented. Within my React component, I have the following interface: interface IPaper { className?: string; children: React.ReactNode; elevation?: 'l ...

Retrieving a string value from a child route in Angular 2

Looking to set the header title from a child route view... In the parent component: @Component({ selector: 'parent-component', template: ` <header>{{headerTitle}}</header> <router-outlet></router-outlet ...

Encountering a 403 status code from the Spotify Web API while attempting to retrieve data using an OAuth 2.0 Token

I'm currently experimenting with the Spotify Web API and attempting to retrieve my most played songs. To obtain an access token for making requests, I am utilizing the client credentials OAuth flow. While I have successfully obtained the access token, ...

Using useState to initialize a long value

Obtaining a very large state from JSON can be challenging, especially when it consists of at least 50 lines. During page generation, an error like "there is no such value" may occur if the initial value is not set and the interface is not assigned properl ...

How to target a particular Textfield in React with its unique identifier

I'm working on a component that contains various Textfields and need to access specific IDs. For example, I want to target the textfield with the label 'Elevator amount'. I attempted the following code snippet but am unsure of how to correct ...

When an empty array is returned from a catch statement in an async/await method, TypeScript infers it as never

Function getData() returns a Promise<Output[]>. When used without a catch statement, the inferred data type is Output[]. However, adding a catch statement in front of the getData() method changes the inferred data type to Output[] | void. This sugge ...

PhantomJS and HTMLUnitDriver are experiencing difficulty locating elements using their id or xpath

I am currently facing a challenge in implementing a browserless solution within my cloud environment due to the lack of Chrome/Firefox installations. Even when using headless Chrome/Firefox solutions, I am encountering difficulties as they still require br ...

Setting up the foundations in Angular 4

Using WebStorm 2017.1.4, I am working on creating the front end of my J2EE application. Within this project, I have two components: "about" and "contacts". In the latter component, my goal is to include all contacts from a MySQL database. However, I encoun ...

Running PHP scripts within an Angular2 CLI application

I'm currently working on an Angular 2 app using Angular CLI, but I've noticed that the PHP files are not being compiled correctly. I'm curious if the server that is included with Angular CLI supports PHP. If not, do you have any recommendati ...

TS: A shared function for objects sharing a consistent structure but with varied potential values for a specific property

In our application, we have implemented an app that consists of multiple resources such as Product, Cart, and Whatever. Each resource allows users to create activities through endpoints that have the same structure regardless of the specific resource being ...

Make sure to wait for the observable to provide a value before proceeding with any operations involving the variable

Issue with handling observables: someObservable$.subscribe(response => this.ref = response); if (this.ref) { // do something with this.ref value } ERROR: this.ref is undefined How can I ensure that the code relying on this.ref only runs after ...

What is the method for converting a string[] array to a record<string, boolean> format in typescript?

I have a string array that contains values I want to keep and use to create a new array called Record. For each value in the userValue array. For example: userValue: string[] = ["1111","2222","3333","4444"]; selectedOptions: Record<string, boole ...

Using Ionic's ngmodel directive with a list and associating ids as keys

Having an issue. Trying to connect a toggle button with a list and use the toggle's id as a key. //Function for conversion transform(d) { alert(d); //when i put this.id here i have undefined value return Number(d); } <ion ...

What is the best way to search for and sort through the data in this particular scenario?

This code snippet is specifically created for extracting and comparing data from the Google spreadsheet shown in the images. exports.processosjudiciais = functions.https.onRequest(async (request, response): Promise<any> => { const jwtClient = ...

Functionality not functioning within Shadow DOM

After creating and exporting an Angular Element as a single script tag (user-poll.js), using the element on a host site is simple. Just include the following two lines: <user-poll></user-poll> <script src="path/to/user-poll.js"></sc ...

Tips for creating a Cypress command chain that includes parameters

Looking for an expander with its caption to click on it. Successfully working: cy.get('[caption="Radio Button"] > .expander-container').click(); Want to turn this into a command. Cypress.Commands.add('findExpanderByName', ...

Updating the JWT token in Angular 6 and making a new request with the updated token

When my JWT authentication token expires (verified by the backend), I need to call a refresh token API and resend the last failed request due to the expired token. I have an Interceptor in place, but I must update the authentication header before sending ...

Retrieve the Document ID from Firebase

I'm currently exploring the functionality of Firebase and enhancing my workflow with "react-firebase-hooks". Is there a way for me to retrieve both the doc id and doc data simultaneously and pass them as props? Currently, I am only able to access the ...

Setting up Angular 2 for ASP.NET MVC: A Step-by-Step Guide

angular.io provides a setup guide for asp.net core at: https://angular.io/docs/ts/latest/cookbook/visual-studio-2015.html. However, I am trying to configure it for an asp.net mvc application. The Quick Start files are already present in the asp.net mvc te ...

In order to showcase the data from the second JSON by using the unique identifier

SCENARIO: I currently have two JSON files named contacts and workers: contacts [ { "name": "Jhon Doe", "gender": "Male", "workers": [ "e39f9302-77b3-4c52-a858-adb67651ce86", "38688c41-8fda-41d7-b0f5-c37dce3f5374" ] }, { "name": "Peter ...