Issue
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>
</div>
Then say events happen in this order:
showPipeis falsearrObspushes [1,2,3]showPipeis 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.
Edit:
My observable is actually just a new Subject() which I call next() on.
Solution
There are some ways you can solve this. I would suggest adding a shareReplay operator on your Observable:
readonly arrObs = this.someDataFromSomewhere().pipe(
shareReplay(1)
);
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>
</div>
</ng-container>
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>
</div>
</ng-container>
Answered By - Poul Kruijt
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.