Handling Observables with NgIf and Async Pipe

Observables

Angular’s async pipe subscribes to an Observable or Promise when the component loads and returns the last emitted value. The async pipe identifies the component that needs to be checked for changes whenever a new value is emitted. It will automatically unsubscribe when the component gets destroyed. Also, when the reference of an expression changes, the async pipe automatically unsubscribes from the current Observable or Promise and subscribes to a new one.

An example of an Async pipe with Observables

We have a simple component that uses the async pipe to subscribe to the currentTime$ observable. The displayed value is automatically updated whenever the observable emits a new value.

import { Component } from '@angular/core';
import { Observable, interval } from 'rxjs';

@Component({
  selector: 'app-root',
  template: `
    <h1>Async Pipe Example</h1>
    <p>Current time: {{ currentTime$ | async }}</p>
  `
})
export class AppComponent {
  currentTime$: Observable<Date>;

  constructor() {
    this.currentTime$ = interval(1000).pipe(
      map(() => new Date())
    );
  }
}
  • The currentTime$ observable is created using the interval an operator from RxJS, which emits a sequential number every 1 second.
  • We then use the map operator to transform the emitted number into a Date object representing the current time.
  • In the template, we use the async pipe to directly bind the value of currentTime$ to the {{ currentTime$ | async }} expression, which will automatically handle subscribing and unsubscribing from the observable.
  • This way, the template will always display the current time, updating every second as new values are emitted by the observable.

When to use ngIf with Async Pipe?

The ngIf directive and async pipe can be used in situations where you want to conditionally display content based on the completion of an asynchronous operation or the presence of data from an asynchronous source.

Here are a few common scenarios where you might use ngIf with async pipe

  1. Data Loading: When fetching data from an API or performing an asynchronous operation, ngIf with async pipe can be used to display a loading message or spinner until the data is loaded and ready to be displayed.
  2. Authentication and Authorization: When implementing authentication and authorization in an application, ngIf with async pipe can conditionally show or hide some UI elements based on the user’s permissions and access rights.
  3. Conditional Rendering: If you have a conditional logic in your template that depends on the result of an asynchronous operation, ngIf with async pipe is used to conditionally render different sections of a template based on the state of the asynchronous operation.

Example of ngIf and Async Pipe

Here, we have an AppComponent that declares an Observables called data$. The data$ observable simulates an asynchronous data retrieval using the of operator and delay operator from RxJS.

import { Component } from '@angular/core'; 
import { Observable, of } from 'rxjs';
import { delay } from 'rxjs/operators';
>
@Component({
  selector: 'app-root',
  template: `
    <div *ngIf="data$ | async as data; else loading">
      <h1>Data is loaded:</h1>
      <p>{{ data }}</p>
    </div>

    <ng-template #loading>
      <h1>Loading data...</h1>
    </ng-template>
  `,
})
export class AppComponent {
  data$: Observable<string>;

  constructor() {
    // Simulating an asynchronous data retrieval
    this.data$ = of('Hello, world!').pipe(delay(2000));
  }
}
  • In the template, we use the ngIf directive to conditionally display content based on the completion of the data$ observable.
  • The async pipe is used to subscribe to the data$ observable and retrieve its value before assigning it to the data variable using the as syntax.
  • Inside the ngIf block, we display the loaded data, and inside the ng-template with the #loading reference, we display a loading message.
  • When the data$ observable emits a value, it will be displayed in the template. Until then, the loading message will be shown.
  • The subscription and the automatic updating of the view when the observable emits new values or when it is completed are handled by the async pipe.

You can simplify your code and let Angular handle subscription management and automatic updates of the view when the asynchronous operation completes or emits new values by using ngIfwith asyncpipe. Overall, ngIf with async pipe allows you to write cleaner and concise code for handling asynchronous operations and conditional rendering in Angular apps.


Similar Articles