Search code examples
javascriptrxjsreactivex

What are the differences between using a Subject and an Observable, and what are the uses for each?


I have learned of two different ways of making an Observable. First one was with a Subject, like so:

// file A
const message$ = new Subject();

// file B
message$.subscribe( (message) => console.log(message) );

// file C
message$.next("Hello there!");

This method of creating an Observable allows me to have a way to exchange data from file B to file C.

The second way is via the Observable class, like so:

// file A
const click$ = new Observable( function(observer) { 
  //Alternatively, I can use Observable.create()
  document.addEventListener('click', (e) => observer.next(e));
});

// file B
click$.subscribe( (cl) => console.log(cl) );

The main difference that I can gather between the Subject way and the Observable way is that I am not sure how to have some sort of communication between some file C, to the subscribers of the Observable. Basically, click$ does not have a .next() method, and the observer methods are in the function that we pass to the observable.

Other than this difference in behavior, is there another difference between observables made with Subject, and those made with Observable


Solution

  • A Subject is both Observable and Observer at the same time. That makes it so tempting to use, because you get a reference to an Observer that you can pass around in your code and emit items from wherever you want. However, that increases the error-proneness of your code by a lot, as you switch from a declarative definition of your Observable to a imperative one.

    Generally speaking, you should use Observable creation functions (of, from, create) wherever possible. I'd say most cases can be solved without Subjects. There is a steep learning-curve though, as you must get to know most of the Observable creation functions in order to follow that pattern.

    Subject might come more natural to developers who are used to code imperatively (that is: with a script language like JS), as it kind of resembles a simple wrapper object for a callback function. And one might ask, why is there a Subject anyway if its not desirable.

    According to this article, Subjects are to be used in one case only:

    To generate a hot observable imperatively and statefully, without any direct external source.

    In short, that means: Use Subject when you don't have any external source (like an Observable, Promise or Event) and need to multicast the state of a class from inside a function. You shouldn't expose that Subject to others, though!

    I suggest reading this article to you, it will clear up things.