- read

How to use Asynchronous Pipe in Angular

The Software Line 34

How to use Asynchronous Pipe in Angular

Learn how to use an asynchronous pipe to show the data from a remote API on a component template in Angular 16

The Software Line
Level Up Coding
Published in
4 min read18 hours ago

--

Photo by EJ Strat on Unsplash

Introduction

In Angular, pipes are specific functions responsible for transforming or converting the data on component templates in some way from input to output value. The value to which we are applying the pipe is the input value for the appropriate pipe function. So, we can use Angular’s built-in pipes or create the custom ones. By default, pipes are pure, which means that the transform method will be invoked only when the input arguments change.

Every pipe represents a class that implements the Pipe Transform interface. An example of a simple custom pipe responsible just for capitalizing the first letter of the input string value is:

import { Pipe, PipeTransform } from '@angular/core';

@Pipe({
name: 'capitalize',
standalone: true,
pure: true // By default - not needed here
})
export class CapitalizePipe implements PipeTransform {

transform(value: string, ...args: any[]): string {
return value
? `${value.charAt(0).toUpperCase()}${value.slice(1)}}`
: value;
}
}

We have a class marked with pipe decorator and the name of the pipe that will be used on the component template. The class implements the Pipe Transform interface and transform method, which accepts two arguments:

  • input value for the transformation
  • additional arguments to be used during the transformation process

Notice that we can have standalone pipes, so it means that we don’t need to add the declaration of the pipe inside the main module of the application.

<span>{{ stringValue | capitalize }}</span>

Asynchronous Pipe

This pipe is very useful when you need to fetch and show the data from the remote API (Application Programming Interface) on component templates. This pipe unwraps the value from the asynchronous primitive.

So, the input value for the pipe transform function is the observable or promise value. The output is the value unwrapped from the input.

The pipe subscribes to an Observable or Promise and returns the latest value it has emitted. When a new value is emitted, the pipe marks the component to be checked for changes. When the component gets destroyed, the pipe unsubscribes automatically to avoid potential memory leaks. Also, when the reference to the expression changes, the pipe automatically unsubscribes from the old Observable or Promise nd subscribes to the new one.

Below, you can find the user list component that is using pipe on the template:

import { HttpClient } from '@angular/common/http';
import { Component } from '@angular/core';
import { Observable, map } from 'rxjs';

export interface User {
id: string;
name: string;
username: string;
email: string;
address: {
street: string;
suite: string;
city: string;
zipcode: string;
geo: {
lat: string;
lng: string
}
}
phone: string;
website: string;
company: {
name: string;
catchPhrase: string;
bs: string
}
}

@Component({
selector: 'app-user-list',
templateUrl: './user-list.component.html',
styleUrls: ['./user-list.component.scss']
})
export class UserListComponent {

users: Observable<User[]>;

constructor(private httpClient: HttpClient) {
this.users = this.httpClient.get('https://jsonplaceholder.typicode.com/users')
.pipe(map((data) => {
const response = data as User[];
return response;
}));
}
}

So, we are fetching users’ data from a JSON placeholder API with an Angular HTTP client service. Then we just cast the response type to the list of users because we have a dedicated user interface with all properties.

Then, we have a user list component template:

<div class="user-list-container">
<ng-container *ngFor="let user of users | async">
<mat-card>
<mat-card-header>
<mat-card-subtitle>
{{ user.username }} / {{ user.email }}
</mat-card-subtitle>
<mat-card-title>{{ user.name }}</mat-card-title>
</mat-card-header>
<mat-card-content>
<div>
<span>
{{ user.address.street }} -
{{ user.address.suite }} -
{{ user.address.city }} -
{{ user.address.zipcode }}</span>
<span>{{ user.phone }} / {{ user.website }}</span>
</div>
</mat-card-content>
</mat-card>
</ng-container>
</div>

So, we are rendering the list of users with the for loop in the template. Then, each user represents the Angular Material Card component with its header and content parts.

As a result we have pretty much basic user interface inside the application:

app users list — basic user interface

Conclusion

Definitely, the most important benefit of using an asynchronous pipe is auto-unsubscribe when a component is destroyed, which means that we are safe from potential memory leaks inside the Angular application. Also, the pipe is dynamic in a way that accepts “observable” or “promise” as the input value. When the reference to the expression changes, the pipe automatically unsubscribes from the old observable or promise and subscribes to the new one.

Thanks for reading.
I hope you enjoyed the article and learned something.