iam1me iam1me - 3 months ago 22
Javascript Question

Hot & Cold Observables - Last Refresh Value

I have a scenario where I want to fetch some piece of data from a server, and where the user can request a refresh of this data. The rest of the page needs to update to reflect the currently loaded iteration of the data.

I am picturing this where I have a hot Observable that publishes the data that it loads. I don't want to retain all the old iterations of the data as 1. I only care about the latest iteration of the data and 2. it could lead to an out-of-memory exception if the user refreshes enough in a given session.

However, I DO want to retain the last published value so that if I dynamically bring up a new component that needs access to that same data, it isn't sending out a new request unnecessarily. For this I need an Observable to sit ontop of the hot observable which will only retain and emit the last emission from the hot observable. Here's a diagram illustrating this idea:

dataStream X - - - - - Y - - - - |>
echoStream X - - - - - Y - - - - |>
subscription1 X - - - - - Y - - - - |>
subscription2 X - Y - - - - |>
subscription3 Y - - |>

echoStream is subscribed to the dataStream. The subscription1, subscription2, and subscription3 are all subscribed to echoStream, but they subscribe at different points. At the time of subscription they get the last value that was emitted from the dataStream, and receive subsequent updates from dataStream.

echoStream is a bit of a mix of a Hot and Cold Observable, having a limited history retention.

Does rxjs provide a standard operator for setting up something like echoStream in the above example?


For what I understood, you could use the shareReplay operator in this form :

echoStream = dataStream.shareReplay(1)

As the documentation says:

Returns an observable sequence that shares a single subscription to the underlying sequence and replays notifications [...]

This operator is a specialization of replay that connects to the connectable observable sequence when the number of observers goes from zero to one, and disconnects when there are no more observers.

So there are two things done here by this operator. When a subscriber subscribes to the stream, it receives immediately the latest value emitted by the stream (or the n latest values or the values emitted in the Xms time window before now - depending on the arguments you passed when calling the operator). That's the replay functionality. Then there is the automatic unsubscription functionality which kicks in when there is no longer any subscriber to the stream.

If you don't care about automatic unsubscription, you could use the replay operator instead, you will get only the replay functionality. For example:

echoStream = dataStream.replay(1)