Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Async pipe observable overwrite flashes the DOM

I am subscribing to an Observable in the DOM using the async pipe like so:

<div *ngIf="item$ | async as item; else loading">
    ....
    <div>{{item.name}}</div>
</div>

All is working fine.

However, I have a refresh method that the user can call and it will make the network request again, and return the item$ observable again.

So, in my ts controller:

this.item$ = this._itemService.getItem(url);

The item is mapped in the service.

But, I am setting item$ again. So while loading, the item in the DOM disappears as it does not exist anymore, and then will come back once the new $item is retrieved.

How do I "refresh" the $item without having item disappear in the DOM?

like image 229
Pezetter Avatar asked Feb 26 '18 22:02

Pezetter


1 Answers

As you said you override item$ and then it takes some time until it emits. So you can use a Subject instead and just make it call the this._itemService.getItem(url):

conts subject = new Subject<string>();

...

this.item$ = this.subject
  .switchMap(url => this._itemService.getItem(url));

Then you use it like you did with item$ | async. When you want to update the Observable you just emit a new URL to the Subject in your component:

this.subject.next(newUrl);

The async pipe will keep the original value displayed until getItem emits a new value but this way it won't blink.

like image 125
martin Avatar answered Sep 19 '22 16:09

martin