Before we begin, Its important to understand that subscribing in Rx is a two step process:
- Create a Stream
- Subscribe to the stream.
Set up:
- Client wants a stream of data
Design Constraint:
- You want to give it out conditionally. It can be due to:
- You are not ready due to lack of availability of business logic. In other words, business logic that governs readiness of the stream will come after client has asked for the stream. The fact that subscription to the stream happens after business logic is available is inconsequential.
- Business logic dictating the availability of stream can change at any time, even after the client has subscribed. We must account for the case where business logic reverts the condition such that stream is no longer available to the subscriber(client).
In other words, whenever you, as an owner of a stream is not sure about giving the stream to potential clients who want to subscribe to it, use a Switch Stream. A Switch Stream allows you to change your mind later without letting the client interfere in any way or know about it.
For example, lets say you have the following stream of longs that client is interested in:
At the time client makes a request for the stream for potential subsequent subscription, you are not certain if you want to give this out or you may not have the stream. You however don't want to stop the client from having some stream and subscribing to it. To compensate for lack of our readiness, lets create a dummy empty stream(of the same type as the actual stream), which we would like clients to have until we decide if we want to hand out the real stream.
What we want to do is the following:
We want to do this in such a way that no action from source or subscriber is required. To simulate the bool condition, we now have a stream of bools which will drive the switch between two streams(real and empty ones):
Now that we have the following three streams,
- Real stream (of type long in this case)
- Empty stream (always of the same type as the real stream)
- Driver stream (always of type bool)
At this point our stream is constructed and is ready for subscription. Following will not do anything as the stream hasn't become hot yet:
However if at this stage, if we do the following and drive our bool stream, we will see that the client has automatically subscribed to the actual stream and is getting data from it:
Similarly, the client can be switched back to empty stream by doing the following:
Switch does subscribe/unsubscribe behind the scenes. To verify this, I went back to subscription snooping discussed here. I altered my streams to log sub/dispose:
Ticking the bool stream to false like this:
shows that empty long stream was subscribed to(due to boolStream.OnNext(false)):
Now if we tick the bool stream to true:
we can see that previously subscribed empty stream has been unsubscribed and actual long stream has been subscribed. Since actual stream is hot, you see the data as well. All this sub/unsub switching is done by Switch behind the scenes:
Summary:
- Consider using Switch operator when you want to conditionally give out the observable.Using switch operator:
- Create the desired stream as you normally would.
- Create an empty stream of the same type as the desired stream.
- Create a bool stream which will tick based on some condition known to the source.
- Create a switch stream which is driven by the bool stream