7
votes

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?

1
Why do you replace the stream? Just send a new value into it, e.g. using a Subject. - jonrsharpe
Thats the answer i am looking for, not sure how to do it. - Pezetter
I'd suggest starting with relevant RxJS docs. I wrote up one method I've used here: blog.jonrshar.pe/2017/Apr/09/async-angular-data.html - jonrsharpe
@jonrsharpe Thanks. I'll read up on that a bit more. Stuck on using a different method with a different http request. Subjects are pretty new to me. Any way to do this with my current setup? - Pezetter
You'll have to change a few things; either have a Subject in your component, subscribe to your services calls manually and update it manually, or point item$ to a subject in your service that you push new values to when you call methods on it. - spongessuck

1 Answers

6
votes

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.