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
- 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.
- 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.
- 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 ngIf
with async
pipe. Overall, ngIf
with async
pipe allows you to write cleaner and concise code for handling asynchronous operations and conditional rendering in Angular apps.