When the component loads, Angular's async pipe subscribes to an Observable or Promise and returns the value that was last emitted. Every time a new value is emitted, the async pipe designates the component that needs to be examined for modifications. When the component is destroyed, it will automatically unsubscribe. Additionally, the async pipe immediately unsubscribes from the current Observable or Promise and subscribes to a new one when the reference of an expression changes.
An illustration of an observable-based async pipe
Our basic component subscribes to the currentTime$ observable via the async pipe. Every time the observable emits a new value, the value that is displayed is automatically updated.
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 should I use Async Pipe with ngIf?
When you wish to conditionally show content based on the outcome of an asynchronous operation or the existence of data from an asynchronous source, you can use the ngIf directive and async pipe.
Here are some typical situations in which ngIf and async pipe might be used.
- Data Loading: ngIf with async pipe can be used to display a loading message or spinner until the data is loaded and ready to be displayed when retrieving data from an API or carrying out an asynchronous action.
- Authentication and Authorization: ngIf with async pipe can conditionally show or hide specific UI components based on the user's permissions and access privileges when implementing authentication and authorization in an application.
- Conditional Rendering: ngIf with async pipe is used to conditionally render different sections of a template based on the status of the asynchronous operation if you have conditional logic in your template that depends on the outcome of an 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));
}
}
TypeScript
- We conditionally display content in the template based on the completion of the data$ observable by using the ngIf directive.
- Before assigning the value to the data variable using the as syntax, the data$ observable must be subscribed to and retrieved using the async pipe.
- The loaded data is shown inside the ngIf block, and a loading message is shown inside the ng-template with the #loading reference.
- The template will show the value that is emitted by the data$ observable. The loading notice will appear until then.
- The async pipe handles subscription and automatically updates the UI when the observable emits new values or when it completes.
By using ngIfwith asyncpipe, you can simplify your code and let Angular handle the management of subscriptions and automated changes of the view when the asynchronous operation finishes or emits new values. In general, you can write more succinct and clear code for managing asynchronous operations and conditional rendering in Angular applications by utilizing ngIf with async pipe.