The use of RxJS Subjects is common, but not without problems. In this lesson we will see how they can be usually safely replaced with plain Observables.
[00:01] Sometimes you may write code in RxJS that uses subjects. While subjects have a legitimate use cases, most of the times, they are actually unnecessary. In this case, for instance, we have a subject called click stream. Whenever a click event happens in this event listener, we will send that event into the subject using the .next method.
[00:21] There are a couple reasons why this is a bad idea. First of all is that the click stream is now exposed here for any other script in the page to send events into it, so you may get confused how does this click stream work. You need to search for all of the usage of .next throughout the whole codebase. That may get confusing.
[00:43] The second reason is that the event listener here is not being disposed. It's actually being attached to the document there and always staying there.
[00:53] We can convert this subject to an observable and eliminate these two problems. We can do that with rx.observable.create. Here, the argument is just what we do when subscribe happens. We just write here the recipe for what should happen when subscribe happens.
[01:17] For instance, we're literally just writing what happens when we subscribe. In that case, we just want to add an event listener on the [inaudible] . That event listener will send the event to the observer instead of sending it directly to the subject. We don't have a subject anymore. We just have the observer and the observable. We're going to send that event there, like this.
[01:49] Obviously, we don't need this part anymore because we already have an event listener, and also the click stream now is an observable, so we don't even have this .next method available. It's only on subjects and observers.
[02:04] We can remove this part and here when we subscribe to the click stream, we're going to just log out something interesting like the x-coordinate of that click. When we run this, we can click here, we can see those x-coordinates in the console.
[02:20] One more thing, I also mentioned removing resources like the event listener. Here we added it to the document but we never removed it, so we can also code this logic inside the subscribe function as well.
[02:32] Here, we can return unsubscribe function and this is the logic that we want to run once the user calls subscription.unsubscribe. Here we do our disposal.
[02:45] For instance, when we subscribe, we get out a subscription. We can keep it like that so that later on we can clean out that subscription. For instance, if we run this code after four seconds, we can call subscription.unsubscribe. That will run the logic that is inside here.
[03:09] For instance, we can do document.remove event listener, four clicks. We need to pass the reference to the same function. This function was actually anonymous. As you can see, there was no name to it. We need to have a name to function here.
[03:29] That's why I'm going to extract this function and I'm going to put it over here. I'm going to call it just listener, is this anonymous function. That's what I'm registering when I add the listener. I'm going to remove that same exact function, like this.
[03:50] This means that once we run this code, I can click for a while but after four seconds, I won't be able to click anymore as you can see, because the subscription was unsubscribed. This is how you can replace subjects with observables and have a lot of benefits from that.
that's very valuable, I can use the first example to convert non-reactive widgets to the ones that support streams
Great video André, thanks!
One note though: Despite being out of scope, using the
share
method here is probably worth mentioning, due to the fact that each subscription toclick$
observable will attach a new event listener to the DOM otherwise.