Using a Subject as an Event Bus

André Staltz
InstructorAndré Staltz

Share this video with your friends

Send Tweet
Published 6 years ago
Updated 4 years ago

Every Subject is an Observer, meaning we can freely use the Observer methods next(), error(), complete() to manually send events to the Subject. This lesson will teach you how to use a Subject as an Event Bus through the Observer methods.

[00:00] Every subject is an observable and an observer, too. The Subscribe method of the observable expects an observer. That's how we were able to pass the subject as the argument.

[00:11] It also means we can freely use the observer methods like Next, and Error, and Complete in order to essentially send a value into the subject. This allows us to manually control the observable that this subject represents.

[00:26] For instance, we could get rid of this observable Subscribe and we could remove that as well. Now, we have only the subject and its observers, A and B. Then, we could do to send the value 1. Then, we can send 2 and 3 like this.

[00:46] Then, when we run this, we see observer A sees those events that we manually passed here. We could also, let's say, do subject.complete to say that this is done.

[00:58] We can even, let's say, set an interval to run every second -- every one second. We're going to deliver a value into that subject, like 10 every second. Then, A is going to see one, two, three. After two second, B arrives at [inaudible] and C is the same.

[01:22] This is a lower level API than using, let's say, operators and creation method, but it may be useful in some cases. Here, for instance, is an example in React. We have this component called Hello that renders a div that has a string inside it.

[01:37] The string has a count. It shows a count, which is initialized to zero. Then, it says, "Hello" and it says the name that was given as a prop. For instance here, we had hello and it could have well been Egghead for instance.

[01:51] It shows first zero, hello, egghead. In the contractor, we also made the subject. It's an event bus basically. That allows us to do this. On click of the div, the handler, we can simply send that event to the subject.

[02:11] Here, we're creating another observable based on the subject, or our event bus, so that every click event will be mapped to plus one. Then, we add all of those plus one numbers. We delay them.

[02:23] This is an observable based on the event bus that we can subscribe to and set the state so that this will show a sum of numbers on the count. When we click many times, it's delayed and it's summed. We can still use RxJS observables and operators. We can also use this event bus pattern so that we can send events like that.

[02:49] Usually, using event buses are not a good idea because you can shoot yourself in the foot. For instance, let's say, you do subject.error for some reason. Then, you may actually, since you're manually controlling it, you may send two errors.

[03:05] That is not a good idea because we're violating the observable contract. Then, many other things don't work properly. Because we're manually controlling it, we have opportunities to doing things wrong.

[03:17] We also lose some benefits of reactive programming, which is we only want to react to things. We don't want to control other entities. That's what we're doing when we use an API like .next. We're essentially controlling this other entity.

[03:33] For instance, if we pass the subject to other modules, then those other modules can control how the subject works. That's basically the opposite of reactive programming.

[03:44] If you do that too much, then there's no point in using RxJS. Still, there are cases where you know what you're doing and then you can use the subject as an event bus for multiple observers.

Viktor Soroka
Viktor Soroka
~ 5 years ago

What do you think Andre about the pattern Angular 2 recommend to use? I mean creating subject as private member of the service and then share the readonly observable from it. In this case we ensure that the service is the only place to emit new data.

~ 4 years ago

I use that pattern alot when needed. One benefit is when trying to listen to changes in network connections. i need some other services and components to be aware or be notified of that changings without implement some "new" instance of network components everytime, that mean using a central service for network and letting the rxjs subject to notified the subscriber when it has been changed.