I'm trying to make an RXJS Observable which will essentially act like a cache. Usually I can just use shareReplay for this, however the data I am trying to cache is based on the user, so needs to reset.
The following does almost what I want:
const myObservable = userProfile.pipe(
switchMap(profile => loadData(profile)),
shareReplay(1)
);
Now the data is loaded on the first subscription and it won't be loaded again until a new user profile comes along. However this does not quite work, because a subscriber that subscribes while the new data is being loaded still receives the old data which is cached. This causes the UI to display the old data from the previous user. To circumvent this I did the following:
const myObservable = userProfile.pipe(
switchMap(profile => loadData(profile).pipe(startWith(null))),
shareReplay(1),
filter(v => v != null)
);
This now works great except for one thing: Once a new user logs in, the data is immediately loaded, even though there are currently no subscribers to myObservable. This happens, because shareReplay never unsubscribes from the source. You can make it do so by using refCount: true - but that will disable the caching behavior I want, because the replay buffer is cleared when there are no more subscribers.
I have no idea how to achieve this using RXJS operators or if I need to write a custom operator.