RxJS

Getting Started With RxJS – Part 3: Hot And Cold Observables


Subscribe On YouTube

Code

Part 1: Setting Up The Development Environment & Creating Observables
Part 2: Subscriptions
Part 3: Hot And Cold Observables

This is part 3 of the RXJS Getting Started series. In this part we’ll dive deeper in the topic of observables and you will learn to difference between Cold and Hot Observables. To give you a better understanding of the underlying concept we’ll apply both types of Observables in a practical sample application.

What’s The Difference BetWeen Cold And Hot Observables

In the last part of this series we’ve have been creating Observables in the following way:

var observable1 = Observable.create((observer:any) => {
    observer.next('Observable One is alive!');
    setInterval(() => {
        observer.next('Observable One');
    }, 5000);
});

We’ve used the Observable.create method to create a new Observable. We’ve also passed the producer function to the call of Observable.create. A producer function is the source of values for your observable. In our case we’re sending out events via observer.next in the producer function.

Creating an Observable in this way is what we call a “cold” Observable. An Observable is cold when the producer is created and activated during subscription. This means that the subscription to this Observable is receiving all values which are emitted. There are no values which have been emitted before or will be emitted afterwards.

In contrast, an Observable is regarded as “hot” when the producer is either created or activated outside of the subscription. As the producer is existing before the Observable and a corresponding Subscription is created values could have been emitted before the Subscription is in place.

Let’s quickly take a look at the definition from the RxJS project itself:

Cold observables start running upon subscription, i.e., the observable sequence only starts pushing values to the observers when Subscribe is called. (…) This is different from hot observables such as mouse move events or stock tickers which are already producing values even before a subscription is active.

Another Example Of A Cold Observable

Let’s adapt the sample application from the last part of this series with the code which you can see in the following listing:

var observable1 = Observable.create((observer: any) => {
    observer.next('Observable One is alive: ' + Date.now());
});

var subscription1 = observable1.subscribe(
    (x:any) => logItem(x, 1)
);

var subscription2 = observable1.subscribe(
    (x:any) => logItem(x, 2)
);

Here we’re creating an Observable and sending out one notification by calling the next method of the Observer. The notification value is a string which is containing the result of Date.now().

For this Observable we’re creating two subscriptions. The first subscription is printing out the notification values to the first column and the second subscription is printing out the values to the second column. The result can be seen in the following screenshot.


Note that the last digit of the timestamp is different. This is showing us that there must have been two separate calls of the next method. This means that the Observable is starting to produce values upon subscription which means that this Observable is cold.

We can also make this effect more clear by introducing again two buttons to subscribe:

<body>
    <h1>RxJS Demo</h1>
    <div class="row">
        <div class="column">
            <center>
                <button id="subscribeBtn1">Subscribe</button>
            </center>
            <ul id="list1"></ul>
        </div>
        <div class="column">
            <center>
                <button id="subscribeBtn2">Subscribe</button>
            </center>
            <ul id="list2"></ul>
        </div>
    </div>
    <script src="/bundle.js"></script>
</body>

Attach corresponding click event handler functions for both buttons and then create the Subscriptions in these event handlers:

document.getElementById('subscribeBtn1').addEventListener('click', () => {
    var subscription1 = observable1.subscribe(
        (x:any) => logItem(x, 1)
    );
});

document.getElementById('subscribeBtn2').addEventListener('click', () => {
    var subscription2 = observable1.subscribe(
        (x:any) => logItem(x, 2)
    );
});

The application should now look like the following:

If you now click on the left button the first Subscription is created and the output appears in the first column:


A click on the right column is creating the second Subscription and the corresponding output with the current timestamp appears on the right side:


Again we’re able to clearly see that the Observable starts to produce values at the time of subscribing, the behavior of a “cold” Observable.

Turning The Cold Observable To A Hot Observable

Let’s try to make the “cold” Observable from the last example “hot”. According to the definition the expectation is that the Observable will then be emitting values independently from the Subscriptions created.

Making a “cold” Observable “hot” is easy by using the RxJS operator share. In order to be able to make use of the share operator let’s first add the following import statement to the top of file index.ts:

import { share } from 'rxjs/operators';

The share operator can be applied to the observable in the following way:

var observable1 = Observable.create((observer: any) => {
    observer.next('Observable One is alive: ' + Date.now());
}).pipe(share());

To apply the share operator we’re passing share() to the call of the pipe method. The pipe method takes an infinite amount of arguments and each argument is an operator you want to apply to the Observable.

Here is what the official RxJS documentation is saying about the share operator:

Returns a new Observable that multicasts (shares) the original Observable. As long as there is at least one Subscriber this Observable will be subscribed and emitting data. When all subscribers have unsubscribed it will unsubscribe from the source Observable.

Let’s test this behavior in the browser again. When opening up the application you’ll first see both columns empty, no values have been received yet, as no subscription is existing:


Create a first subscription by clicking on the button on the left:

As the first subscription for the Observable is created the value is emitted and thus the output becomes visible in the left column.

Now, let’s create the second subscription by clicking on the right button. In contrast to what we’ve seen before there is no new notification in the second column. The next call is only made once (when the first subscription is created). Therefore the second subscription is not receiving any notification. This is the behavior of a “hot” Observable.

In general we can say that we should be dealing with a “hot” Observable whenever we subscribe to something that is generating values no matter if someone is listening or not. When we subscribe to such a “hot” Observable, we don’t see past values but only new ones that were generated after our subscription.

What’s Next

Now that you have sound understanding of Observable, Observers and Subscriptions we’ll introduce a new RxJS object type in the next part: Subject.

A Subject is a sort of bridge or proxy that acts both as an observer and as an Observable. You can use a subject to subscribe all the observers, and then subscribe the subject to a back-end data source. You can use subjects to implement a custom observable with caching, buffering and time shifting. In addition, you can use subjects to broadcast data to multiple subscribers.

Stay tuned …

ONLINE COURSE: RxJS 6 In Practice

Check out the great RxJS 6 In Practice course with hundreds of students already enrolled:

RxJS 6 In Practice

  • Learn numerous RxJs Operators, learn all RxJs and Reactive Programming core concepts via Practical Examples
  • Learn the RxJs library via Practical Examples
  • Understand in detail the core notions of Reactive Programming

  • Become familiar with an extended subset of RxJs Operators

  • Learn how to design and build Applications in Reactive style

Go To Course


Using and writing about best practices and latest technologies in web design & development is my passion.