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.


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


  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.


  • sit_in
    sit_in 回复

    Surround your structure in an ng-container which contains the async pipe and stores the value in a variable using as. Also use the ng-if directive to load the container only after you get a value in that async pipe.

    <ng-container *ngIf="( arrObs| async ) as array">
        <div *ngIf="showPipe">
            <div *ngFor="let item of array">{{item}}</div>
  • 无言以对
    无言以对 回复

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

    readonly arrObs = this.someDataFromSomewhere().pipe(


    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>