Home Angular Tutorials Mastering Asynchronous Operations in Angular with zone.js

Mastering Asynchronous Operations in Angular with zone.js

by aouidane.med.amine
29,253 views 10 min read

In this article, we’ll explore how to use zone.js and other Angular APIs to manage asynchronous operations and ensure that our applications remain performant and responsive.

We’ll start by discussing the basics of asynchronous operations and the challenges they pose for web applications.

From there, we’ll dive into the zone.js library and explore how it allows us to track asynchronous operations and trigger change detection cycles in response.

Table of Contents

Importance of asynchronous operations in Angular

Generally, An asynchronous operation in programming is a process that executes apart from the main program flow.

The application keeps running while the job is running in the background, rather than waiting for it to finish before going on to the next one.

Angular uses asynchronous operations extensively, especially for tasks like making HTTP requests, reading and writing data from a database, and handling user input events.

By using asynchronous operations, Angular can continue to update the user interface and respond to user interactions while these tasks are running in the background

However, managing asynchronous operations can be challenging, especially when it comes to handling errors, tracking progress, and triggering change detection cycles.

This is where zone.js and zoneAwareCallback come in.

They provide a way to manage and track asynchronous operations in a more efficient and organized way, which can greatly improve the performance and reliability of Angular applications

 

Role of zone.js in managing asynchronous operations

Zone.js’ primary function in managing asynchronous operations is to provide a way to detect when an asynchronous activity has completed to run a change detection cycle.

This is important because many asynchronous operations in Angular can update the user interface, and it’s important to trigger change detection so that those updates are reflected in the UI.

Zone.js also provides a way to handle errors that occur within asynchronous operations.

By wrapping an asynchronous operation with a zone, you can catch any errors that occur within that operation and handle them in a more controlled way.

 

Wrap asynchronous operations with zone.js

When working with asynchronous operations in Angular, it’s important to track their progress and handle errors to ensure that your application remains responsive and stable.


Zone.js provides powerful tools for managing asynchronous operations, including the ability to wrap those operations in a zone and track their progress.

You can utilize the zone.run() method provided by ngZone to encapsulate an asynchronous operation.

You could, for instance, wrap an asynchronous activity that sends an HTTP request in the related zone.

				
					this.ngZone.run(() => {
  this.http.get('https://xpertuto.com/data').subscribe((data) => {
    // Handle the response data here
  }, (error) => {
    // Handle any errors that occur
  });
});

				
			

By wrapping the HTTP request in a zone using ngZone.run(), any asynchronous operations that are triggered by the request (such as Promise callbacks or other Observables) will also be tracked by zone.js.

This means that you can be sure that your application will stay responsive and that change detection will be triggered appropriately.

In addition to wrapping asynchronous actions in a zone, zone.js can also be used to deal with potential issues that may occur.

You can accomplish this by using the onError() method offered by the zone :

				
					this.ngZone.onError.subscribe((error) => {
  // Handle the error here
});

				
			

By subscribing to the onError() method, you can handle any errors that occur within the zone.

This can be particularly useful for tracking errors that occur during asynchronous operations.

 

The role of zoneAwareCallback

The role of zoneAwareCallback is to wrap a function in a zone, which allows Angular to track asynchronous operations and trigger change detection cycles when they complete.

When an asynchronous operation is executed within a zone, it is tracked by the zone, which means that Angular can detect when the operation completes and run change detection to update the UI with any changes.

Now, using a regular example, let’s take a look at what happens step by step when we click a button to fetch data:

				
					import { Component} from '@angular/core';
import { HttpClient } from '@angular/common/http';

@Component({
  selector: 'app-root',
  template: `
    <button (click)="getData()">Get Data</button>
     <ul>
      <li *ngFor="let item of items">{{ item }}</li>
    </ul>
  `
})
export class AppComponent {

  items: string[] = [];
  
  constructor(private http: HttpClient) { }

  getData() {
  this.http.get('https://xpertuto.com/data').subscribe((data) => {
  this.items = data;
  }, (error) => {
    // Handle any errors that occur
  });
}

				
			

 

  1. When the button is clicked, the event is intercepted by Angular, which creates a task and adds it to a task queue.
  2. Angular’s zone.js library intercepts this task and creates a new zone to track its execution.
  3. Within the new zone, we use the zoneAwareCallback() function to perform the Http asynchronous operation
  4. Once the response is received, a new task is added to the task queue
  5. zone.js intercepts the task and creates a new zone
  6. Within the new zone, Angular starts a new change detection cycle by calling the tick() method of the ApplicationRef service.
  7. Angular runs change detection on the components affected by the new data, updating their views to reflect the new values.

Run Change Detection Using tick() Method

The tick() method is a method of the ApplicationRef class in Angular.

It is used to manually trigger a change detection cycle for the entire application. When called, Angular will check for changes in all components and their child components and update the view accordingly.

Normally, Angular automatically triggers change detection whenever an event occurs, such as a button click or data input.

However, there are certain cases where change detection may not occur automatically, such as when data is fetched from an external source.

In these cases, the tick() method can be used to force a change detection cycle

Here’s the code for the tick() method inside the ApplicationRef:

				
					tick(): void {
  // schedules a microtask to be executed at the end of the current zone
  scheduleMicroTask(() => {
    // runs change detection for the entire application
    this._views.forEach((view) => view.detectChanges());
    // invokes the `onStable` callbacks registered with the `NgZone`
    this._zone.onMicrotaskEmpty.emit(null);
  });
}

				
			

As you can see, the tick() method schedules a microtask using the scheduleMicroTask() function provided by zone.js.

This microtask will be executed at the end of the current zone, after any pending tasks have been completed.

When the microtask is executed, the tick() method runs change detection for all views that have been registered with the ApplicationRef.

It then invokes the onMicrotaskEmpty callback of the NgZone instance, which allows other parts of the application to perform tasks that depend on the completion of the current microtask.

 

References and Links

You may also like