Angular async pipe – How to use it properly in Angular?

The angular async pipe is an angular built-in pipe and impure pipe. The async pipe allows data obtained asynchronously and displays the latest value upon every change. Under the hood, it uses Promise or Observable depending if your async data comes from a Promise or an Observable.

It takes an Observable or a promise as input and subscribes to it automatically. Async pipe also handles the unsubscribing of Promise and Observable without necessitating any further lines of code. We have learned in previous articles on angular built-in pipes.

Prerequisites:
To create and run an Angular project, We need node js and Angular CLI already install in our system, if not then check how to install node js and angular in Ubuntu. Also, need basic knowledge of Angular and had already install IDE like visual studio code. To install or have the latest version of Angular CLI, open a terminal and run the following command:

npm install -g @angular/cli

Syntax of Angular async pipe

The expression can take a value of either Observable or a Promise type. Async pipe automatically unsubscribed when the component gets destroyed.

<element>
{{ <expression> | async }}
</element>

Advantages of Async Pipe in Angular

Angular AsyncPipe is a convenient function that makes rendering data from promises or observables much easier.

  • Async pipe automatically handles observable subscribe and unsubscribe. So we don’t need to handle unsubscribe from the observable when the component is destroyed.
  • We don’t need to call subscribe on our observable and store the intermediate data on our component.
  • Async Pipe makes the rendering of data from observable and promise easier.

Setting up and configure the project for Angular async pipe.

Let first create our angular project and we’ll demonstrate the Angular async pipe example.

  • Angular async pipe example with promise.
  • Async pipe with ngIf example
  • Angular async pipe with ngFor directive.
  • Angular async pipe with service
ng new asyncApp

To demonstrate Angular async pipe with HTTP GET, we need to import the HTTPClient module and formsModule. Let import both modules in the app.module.ts file.

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { HttpClientModule } from '@angular/common/http';
import { FormsModule } from '@angular/forms';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    HttpClientModule,
    FormsModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

Example of Angular async pipe

We will demonstrate a simple async pipe with a promise. The async pipe returns an empty string until the data is finally available (i.e. until the promise is resolved, in case of a promise).

We had applied async pipe to the variable asyncGreeting. Is a promise, will be resolved after 3 seconds. Once the promise is resolved, we can see our greeting “Hello all, Async pipe Greeting from Edupala” in the browser.

import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  template: `
  <div class="p-2 border bg-light">
    <div>{{ asyncGreeting | async }}</div>
  </div>
  `,
  styleUrls: ['./app.component.scss']
})
export class AppComponent {

  asyncGreeting = new Promise(resolve => {
    setTimeout(() => resolve('Hello all, Async pipe Greeting from edupala'), 3000);
  });
}

Angular async pipe with ngIf

The ngIf directive makes it easier to bind async data to our Angular templates. Angular has an Rxjs library that allows us to handle asynchronous data. Typically we get this async data through Angular’s HTTP service which returns an Observable with our data response. We have to use Angular async pipe with HTTP GET methods with ngIf.

angular async pipe ngif
Angular async pipe in ngIf
import { Component, OnInit } from '@angular/core';
import { HttpClient } from '@angular/common/http';

@Component({
  selector: 'app-root',
  template: `
  <div class="p-2 border bg-light">
    <h3>Angular 9 async pipe ngIf Example</h3>
    <p *ngIf="(req$ | async) as country; else loading">
      Name: {{ country[0].name }} <br>
      Region: {{ country[0].region }} <br>
      Capital : {{ country[0].capital }}
    </p>

    <ng-template #loading>
      Loading...
    </ng-template>
  </div>
  `,
  styleUrls: ['./app.component.scss']
})
export class AppComponent implements OnInit {
  req$;

  constructor(private httpClient: HttpClient) { }

  ngOnInit() {
    this.req$ = this.httpClient.get('https://restcountries.eu/rest/v2/name/india?fullText=true');
  }
}

To use httpClient we need to import HttpClientModule in our app.module.ts file. We have the httpClient get method to get JSON array object containing information about country India from restcountries.eu API.

We have req$ | async as the country local template variable in the *ngIf. This local template variable country that Angular assigns the value from the Observable req$.

Angulare Async pipe with ngFor – Angular ngFor async pipe example

The ngFor directive can’t alone handle asynchronous operation. We need an async pipe. Let’s explore how we can handle NgFor alongside the async pipe to subscribe to an Observable. In the example below, we try to display a list of frameworks based on an Observable. The async pipe takes care of subscribing/unsubscribing to Observable streams for us.

Agnular async pipe ngFor
import { Component } from '@angular/core';
import { Observable } from 'rxjs';

@Component({
  selector: 'app-root',
  template: `
  <div class="p-5">
	  <h4>Async pipe angular - 12</h4>
	  <ul>
	    <li *ngFor="let framwork of frameworks | async">
	    {{ framework }}
	    </li>
	  </ul>
	  <button class="p-2" (click)="checkframework()">Check framework</button>
  </div>`,
  styleUrls: ['./app.component.scss']
})
export class AppComponent {
  frameworks: Observable<string[]>;

  constructor() { }

  checkframework() {
    this.frameworks = new Observable(observer => {
      setInterval(() => observer.next([
        'Angular',
        'React',
        'Vue']), 1000);
    });
  }
}

We have a button and clicking on it will call method checkFramework(). This method will create observable and assign its value to our property framework. We are going to render an unordered list of the framework from observable in ngFor using async pipe.

Implementing Angular Async pipe with service

We have demonstrated an Angular async pipe with ngFor and ngIf. In a real application, we keep Angular data state through ngRx or using service. Let’s create an Angular service called the countries.service.ts to implement async pipe.

ng generate service services/countries

Edit countries.service.ts file to add two methods, one to retrieve information about all countries and the second method to retrieve detailed data on a particular country. Both these methods will implement using async pipe.

import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';

@Injectable({
  providedIn: 'root'
})
export class CountriesService {

  constructor(private http: HttpClient) { }

  getCountryDetail(countryName: string): any {
    const url = 'https://restcountries.eu/rest/v2/name/' + countryName + '?fullText=true';
    return this.http.get(url);
  }

  getCountries(): any {
    const url = 'https://restcountries.eu/rest/v2/all';
    return this.http.get(url);
  }
}
Angular async pipe service

Edit app.component.ts file as.

import { HttpClient } from '@angular/common/http';
import { Component, OnInit } from '@angular/core';
import { Observable } from 'rxjs';
import { CountriesService } from './services/countries.service';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent implements OnInit {
  title = 'Angular Async Pipe';
  countryName: string;
  countryObj$: Observable<any>;
  countriesList$: Observable<any>;

  constructor(private countryService: CountriesService) { }

  ngOnInit(): void {
    this.countriesList$ = this.countryService.getCountries();
  }

  getCountryInfo(country: string): void {
    this.countryObj$ = this.countryService.getCountryDetail(country);
  }
}

Edit app. component template file to add select element and button to display detailed information about a particular country.

<div class="async-http">
  <h4>Angular async pipe with HTTP GET</h4>
  <select [(ngModel)]="countryName">
    <option *ngFor="let country of countriesList$ | async" value="{{ country.name }}">
      {{country.name}}
    </option>
  </select>
  <button (click)="getCountryInfo(countryName)">Get Country Details</button><br /><br />
  <div *ngIf="(countryObj$ | async) as countryObj">
    <h1>{{ title }}</h1>
    <h3>Name : {{ countryObj[0].name }}</h3>
    <h3>Capital : {{ countryObj[0].capital }}</h3>
    <h3>Currency : {{ countryObj[0].currencies[0].code}}</h3>
    <img src="{{ countryObj[0].flag }}" width="400" height="300">
  </div>
</div>

<router-outlet></router-outlet>

Conclusion
In this tutorial, we have explored the Async pipe in the Angular project. We have demonstrated an example of different use cases of Angular async pipe in the ngIf and ngFor loop. We have also seen how we can use AsyncPipe in our application using Promises or Observables. If you want to make reference to our code, check the angular async example of our code in the GitHub repository.

Related Articles

Spread the love

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top