1. What is an Async pipe?
==> The Async pipe is a pipe that essentially does these three tasks: It subscribes to an observable or a promise and returns the last emitted value. Whenever a new value is emitted, it marks the component to be checked. That means Angular will run Change Detector for that component in the next cycle. It unsubscribes from the observable when the component gets destroyed.
2. Why should we use Angular’s async pipe?
- If you subscribe() to an Observable or Promise you’ll need to unsubscribe() at the end of your component’s life cycle to avoid memory leaks.
- Change detection works splendidly with the Async pipe.
- We don’t have to unsubscribe manually because the AsyncPipe handles this for us.
- Also, as a best practice, it is advisable to try to use a component on the onPush change detection strategy with an Async pipe to subscribe to observables.
>> Angular AsyncPipe example(s):
==> Angular AsyncPipe with Observables :
import { Component, OnInit } from '@angular/core'; import { Observable, timer } from 'rxjs'; @Component({ selector: 'app-timer', template: ` <p>Timer: {{ $timer | async }}</p> `, styleUrls: ['./timer.component.css'] }) export class TimerComponent implements OnInit { $timer: Observable<Number>; constructor() { } ngOnInit(): void { this.$timer = timer(1000, 1000); } }
==> Angular async pipe with Promises :
import { Component, OnInit } from '@angular/core'; @Component({ selector: 'app-people', template: ` <p>{{ $observable | async }}</p> `, styleUrls: ['./people.component.css'] }) export class PeopleComponent implements OnInit { $observable: Promise<any>; constructor() { } ngOnInit(): void { this.$observable = Promise.resolve(["Jim", "Dick", "Harry"]); } }
==> Promise with a timer :
import { Component, OnInit } from '@angular/core'; @Component({ selector: 'app-timer', template: ` <p *ngIf="($observable | async) as time">Current Timer Value: {{ time }}</p> `, styleUrls: ['./timer.component.css'] }) export class TimerComponent implements OnInit { $observable: Promise<any>; constructor() { } ngOnInit(): void { this.$observable = new Promise((resolve, reject) => { setTimeout(() => { resolve('foo'); }, 3000); }); } }
==> Async pipe with HTTP CLIENT :
import { Component, OnInit } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { Observable } from 'rxjs'; class Activity { activity: string; type: string; link: string; } @Component({ selector: 'app-activity', template: ` <h1>Activity Summary</h1> <div *ngIf="($activity | async) as activity; else loading"> <p>{{ activity.activity }}</p> <p>{{ activity.type }}</p> </div> <ng-template #loading> <p>Loading...</p> </ng-template> `, styleUrls: ['./activity.component.css'] }) export class ActivityComponent implements OnInit { $activity: Observable<Activity>; constructor(private httpClient: HttpClient) { } ngOnInit(): void { this.loadActivity(); } loadActivity() { this.$activity = this.httpClient.get<Activity>("https://www.boredapi.com/api/activity"); } }