[Fixed] Async pipe within ngIf directive


When using the AsyncPipe inside of an *ngIf, if the Observable connected to the AsyncPipe pushes its values before the *ngIf becomes true, the value returned from the AsyncPipe will be incorrect.

For example, let’s say I have:

<div *ngIf="showPipe">
    <div *ngFor="let item of arrObs | async">{{item}}</div>

Then say events happen in this order:

  1. showPipe is false
  2. arrObs pushes [1,2,3]
  3. showPipe is set to true

From what I’ve seen, the *ngFor will act as if arrObs | async returned null.

One solution to this problem is to use [hidden] instead, but there are a lot of benefits to *ngIf, like performance and making null handling easier.

What’s the proper way to do this? Should I just not use an observable at all for displaying content? I had assumed that using an observable was the most Angular-y way of doing things.

My observable is actually just a new Subject() which I call next() on.


There are some ways you can solve this. I would suggest adding a shareReplay operator on your Observable:

readonly arrObs = this.someDataFromSomewhere().pipe(

if your Observable is actually a Subject, you can also change it to a BehaviorSubject or ReplaySubject

This way you will always receive the most up to date data on subscription.

There are also ways to handle this in the template and still maintain the *ngIf benefits:

<ng-container *ngIf="arrObs | async as arr">
  <div *ngIf="showPipe">
    <div *ngFor="let item of arr">{{item}}</div>

Or if you don’t want the *ngIf to wait for the observable

<ng-container *ngIf="{ arr: arrObs | async } as data">
 <div *ngIf="showPipe">
   <div *ngFor="let item of data.arr">{{item}}</div>

Leave a Reply

(*) Required, Your email will not be published