Explanation of AsyncPipe in Angular

Posted on 2025-05-26 by Burak Hamdi TUFAN
Web
Explanation of AsyncPipe in Angular
Hello everyone, in this article we are going to talk about async pipe which is one of most the powerful built-in features in Angular to handle asynchrone operations.

Let's get started

The AsyncPipe is one of Angular’s most powerful built-in features. Async pipe has been designed to work with Observable and Promise data sources to handle the delayed data in templates. It simplifies subscription management, prevents memory leaks, and enhances code readability.

What is the AsyncPipe?

AsyncPipe is a one of the built-in Angular pipe which automatically subscribes to an Observable or Promise and returns the latest emitted value. It also unsubscribe when the component is destroyed to handle memory leaks. Here we need to be carefull, if our component will stay more, we should take care the unsubscription.
Here is the syntax example

{{ observableOrPromiseDataVariable | async }}

Here observableOrPromiseDataVariable is providing the data with the help of the Observable or Promise. And we use async pipe to handle the data.

Why to Use the AsyncPipe?

If we don't need to process the Observable data source, it is easier to use it in smaller parts. Due to its design is to subscribe and unsubscribe automatically. So, some dummy components we dont need to handle the unsubscription also if not necessary.
Here is the example of traditional way to use it in ts component.

export class MyComponent implements OnInit, OnDestroy {
  data!: any;
  private subscription!: Subscription;

  ngOnInit(): void {
    this.subscription = this.myService.getData().subscribe(res => {
      this.data = res;
    });
  }

  ngOnDestroy(): void {
    this.subscription.unsubscribe();
  }
}

Here we will call the api and make the subscription, Assign the data to a variable and at the destruction, handle the unsubscription.

With AsyncPipe, this becomes easier and declerative:

<div *ngIf="myService.getData() | async as data">
  {{ data }}
</div>

With async pipe, it will automatically fetch the data and show it in the related place and unsubscribe it when the comppnent destroyed.

Using AsyncPipe with Observable

Let's improve our examples and see how we can use the async pipe with an Observable in a real world example:
Service File: user.service.ts

@Injectable({ providedIn: 'root' })
export class UserService {
  constructor(private http: HttpClient) {}

  getUsers(): Observable<User[]> {
    return this.http.get<User[]>('https://jsonplaceholder.typicode.com/users');
  }
}
This service will fetch a online mock user list from the given url.
Component File: user-list.component.ts

@Component({
  selector: 'app-user-list',
  templateUrl: './user-list.component.html'
})
export class UserListComponent {
  users$ = this.userService.getUsers(); // Observable<User[]>
  constructor(private userService: UserService) {}
}
This component has the declared Observable variable which is assigned the api call to fetch the users from the service.
Template File: user-list.component.html

<ul>
  <li *ngFor="let user of users$ | async">
    {{ user.name }} - {{ user.email }}
  </li>
</ul>
Async pipe here is waiting for the Observable emits the data, and when the data is there then handle the rendering. ALso it handles the unsubscription automatically.

Using AsyncPipe with Promise

Above we have made an example with Observable. We can also use the async with Promise. Let's make an example with Promise as well


@Component({
  selector: 'app-promise-example',
  template: `
    <div *ngIf="promiseData | async as data; else loading">
      {{ data }}
    </div>
    <ng-template #loading>Loading...</ng-template>
  `
})
export class PromiseExampleComponent {
  promiseData: Promise<string>;

  constructor() {
    this.promiseData = new Promise(resolve =>
      setTimeout(() => resolve('Data loaded from promise!'), 2000)
    );
  }
}
Above you can see in the constructor we have fetched the data and assigned to the variable direclty. In template side it will be handled automatically by async pipe.

Common Pitfalls

  • Memory Leaks: Pay attention to memory leaks if you are doing manual and auto unsubscribing.
  • Multiple evaluations: Every async pipe re-evaluates the Observable. ESo improve the cache usage and dont try to use async in same stream.
  • Handling null/undefined: Ensure observables emit values before accessing nested properties.

Testing Components with AsyncPipe

To test the async in the components, we need to use fakeAsync and inside the function we need to use the tick function. tick makes the function is to wait until the observables emits the value

Below you can see a test example

it('should render user name', fakeAsync(() => {
  const fixture = TestBed.createComponent(UserListComponent);
  fixture.detectChanges();
  tick(); // wait until observable emits
  fixture.detectChanges();
  expect(fixture.nativeElement.textContent).toContain('Leanne Graham');
}));

Conclusion

Async pipe is one of the fundamental built-in util of Angular. It makes asynchoronous data handling simplier and reducing the boiler plate. The nature of async pipe is to proceed declerative and avoiding manual subsciption and unsubscription. If you’re dealing with data in Observables or Promises in Angular, using effectively AsyncPipe is a really important. Use it and you will see your templates become cleaner and more reactive.

That is all.

Happy asynchoronous data handling.

Burak Hamdi TUFAN


Tags
Share this Post
Send with Whatsapp