Reputation: 13
I'm trying to cache the emitted value of an observable to filter out irrelevant future emits.
I have a route:
{ path: "user/:id/:type", component: UserComponent }
Within that component i'm getting the ActivatedRoute
params, switchMap
to the actual http call, and using async
pipe on template to show the user details.
user$: Observable<User>;
ngOnInit() {
this.user$ = this.route.params.pipe(
switchMap(params => {
return this.http.getUser(params.id)
})
);
}
in the template it self:
<div *ngIf="user$ | async as user">
<span>{{ user.id }}</span>
<span>{{ user.name }}</span>
</div>
I would like to filter out this.route.params
values, if the route changes but the :id
param stays the same.
I was thinking something like
user$: Observable<User>;
ngOnInit() {
this.user$ = this.route.params.pipe(
withLatestFrom(this.user$ || Observable.from({})),
filter( ([params, user]) => {
return (params.id !== user.id); // filter if params id equals to last fetched user
}),
switchMap(params => {
return this.http.getUser(params.id)
})
);
}
but withLatestFrom
comes up null.
i would like to avoid caching it using a tap operator, and just come up with a clean alternative, somewhere like the road i tried to take. what am i missing ?
Upvotes: 1
Views: 694
Reputation: 31125
To compare the value only with the last emission, you could use RxJS pluck
operator to select the id
property and distinctUntilChanged
operator to ignore the notifications until the id
is changed.
Try the following
ngOnInit() {
this.user$ = this.route.params.pipe(
pluck('id'),
distinctUntilChanged(),
switchMap(id => {
return this.http.getUser(id)
})
);
}
Or to ignore all the duplicates and trigger the HTTP request only for distinct id
s, you could RxJS distinct
operator.
ngOnInit() {
this.user$ = this.route.params.pipe(
distinct(params => params['id']),
switchMap(params => {
return this.http.getUser(params.id)
})
);
}
Upvotes: 1