Async Pipe In Angular
In this article, we will learn how to use async pipe. The async pipe lets us subscribe to an Observable or Promise from the template and get the value emitted back. When the component loads, the async pipes subscribe to the observable. When the component is destroyed, it unsubscribes. We will go through the syntax and an example using observable, as well as how to use it with ngIf and ngFor. How to share a subscription with the help of ShareReplay. To save the result, use the as operator. It can be used with the httpClient and HTTP get requests, for example.
Syntax of Async Pipe
The async pipe has the following syntax. The result of an expression must be an observable or a promise. The keyword async is followed by the pipe symbol |. With interpolation syntax, we're using the async pipe.
{{expression | async}}
Example
obsValue = new Observable((observer) => { console.log("Observable starts") setTimeout(() => { observer.next("90000") }, 1000); })
It's possible to use it in the template as shown below.
{{ obsValue | async}}
Use the async pipe with ngIf
<div *ngIf="(obsValue | async); else elseBlock"> {{ obsValue | async}} </div> <ng-template #elseBlock> Observable is loading. Please wait </ng-template>
<div *ngIf="(obsValue | async); else elseBlock"> //obsValue Subscribed here {{ obsValue | async}} //obsValue Subscribed here again </div>
ShareReplay
obsValue = new Observable((observer) => { console.log("Observable starts") setTimeout(() => { console.log("Returns value") observer.next("1000") }, 5000); }).pipe(shareReplay());
There are no changes to the component code that are required. However, there is one extra if block in this case. bringing the total number of async pipes to three
<div *ngIf="(obsValue | async); else elseBlock"> {{ obsValue | async}} </div> <ng-template #elseBlock> Observable is loading. Please wait </ng-template> <div *ngIf="(obsValue | async);"> observable has recevied data </div>
Using ngIf “as” syntax
<div *ngIf="(obsValue | async) as value; else elseBlock"> {{ value}} //works only inside the If Block </div> <ng-template #elseBlock> Observable is loading. Please wait </ng-template> {{ value}} // will not work
Check the observable after removing the shareReplay.
obsValue = new Observable((observer) => { console.log("Observable starts") setTimeout(() => { console.log("Returns value") observer.next("1000") }, 5000); });
Use the async pipe with ngfor
{"message":["afghan","basset","blood","english","ibizan","plott","walker"],"status":"success"}
hounds: Observable<any> = this.getHoundList();
getHoundList(): Observable<any> {
return this.http.get<any>("https://dog.ceo/api/breed/hound/list")
}
To subscribe to the hounds observable, use the (hounds | async) in the template. Isn't it true that we're using a safe navigation operator ? before the message with the property name i.e., it's null at first till the outcome arrives, and without ? Errors will appear in your console.
<ul> <li *ngFor="let breed of (hounds | async)?.message">{{breed}}</li> </ul>
You can can use ngIf and ngFor together with the as keyword to save the result in breeds.
<div *ngIf="(hounds | async) as breeds"> <ul> <li *ngFor="let breed of breeds.message">{{breed}}</li> </ul> </div>
ngIf is used in the following code to display a random image of a dog.
Open app.component.ts file and put the following code:
//component randomPic: Observable<any> = this.getRandom(); getRandom(): Observable<any> { return this.http.get<any>("https://dog.ceo/api/breeds/image/random") }
Open app.component.html file and put the following code:
//Template <img src="{{ (randomPic | async)?.message}}">