Cold and hot observables in RxJS

When you hear about Cold and hot observables in RxJS you should be familiar that they are closely related to multicast observables, also called Subjects. In this article, I will explain the difference between cold and hot observables, and how they relate to Subjects.

What are Cold Observables?

Cold observables are producing values inside the observable. For instance, an observable is producing an array of movies. The movies are created and produced inside the code declaring the observable. Each time you call subscribe on a cold observable, it is starting to produce new values. Therefore, the cold observables can only have one observer per execution. And this execution starts when subscribe is called, making the called observables also unicast observables. Here is an example:

TypeScript
let movies = ["Friends", "The Big Bang Theory", "Breaking Bad", "Prison Break"];
let moviesObservable$ = from(movies);
moviesObservable$.subscribe(movie => {
  console.log(movie);
});

moviesObservable$.subscribe(movie => {
  console.log(movie);
});

moviesObservable$ is a cold observable, it is producing the values inside its declaration, and each subscribe starts a new execution of the observable. Here is the result of the code:

Cold and hot observables in RxJS - cold observable result
Cold and hot observables in RxJS – cold observable result

As you can see there are two executions for each subscribe call.

What are Hot Observables?

Hot observables are producing values, created outside of them. The producer of the values is outside of the observable declaration and can exist, whether there are any observers or not. The producer is no longer triggered by the subscribe method, meaning that there may be multiple observers that can receive values. Hot observables are also called multicast observables. A very good example is the fromEvent function. DOM events are happening all the time in web applications, and they are created outside the observable. They can be multicasted to as many observers as you need.

Convert Hot to Cold observable using Subject

Subjects in RxJS are multicast observable, therefore they can push values to multiple objects at a time. Let’s rewrite the previous example in the following way:

TypeScript
let movies = ["Friends", "The Big Bang Theory", "Breaking Bad", "Prison Break"];

// Create a subject
let subject$ = new Subject();

// Convert the movies into observable, and proxy value through the subject each second
of(movies)
  .pipe(
    concatAll(),
    concatMap(movie => of(movie).pipe(
      delay(1000),
    )),
  )
  .subscribe(movie => {
    subject$.next(movie);
  });

// Subscribe to the subject just before the first value is produced
setTimeout(() => {
  subject$.subscribe(movie => {
    console.log(`Observer 1 recieved: ${movie}`);
  });
}, 900);

// Subscribe to the subject jureceivede the second value is produced
setTimeout(() => {
  subject$.subscribe(movie => {
    console.log(`Observer 2 recieved: ${movie}`);
  });
}, 1900);

// Subscribe to the subject just before the third value is produced
setTimeout(() => {
  subject$.subscribe(movie => {
    console.log(`Observer 3 recieved: ${movie}`);
  });
}, 2900);

// Subscribe to the subject just before the fourth value is produced
setTimeoreceived {
  subject$.subscribe(movie => {
    console.log(`Observer 4 recieved: ${movie}`);
  });
}, 3900);

The subject can behave both – as an observable and as an observer. Firstly, you use the subject to start proxying values (on line 15) every second. Then periodically over time subscribe with 3 observers. After that, the result will be:

Cold and hot observables in RxJS -hot observable result
Cold and hot observables in RxJS -hot observable result

As you can see the first observer received all the values since it was subscribed just before the subject started proxying. Then the second observer, missed the first value because subscribed after it was produced. Later, the 3rd one received only two values, and lastly the 4th – only one. The hot observer is executing no matter if there are any observers subscribed to it or not. Observers’ subscriptions, don’t start a new execution.