Angular has many types of Observables which you can use. Maybe you've seen Subject, BehaviourSubject, ReplaySubject, or AsyncSubject in Angular examples and wondering what they are and when you can use them.
In this post, I want to dive deeper into what those types of Subjects are and when you should use them. So buckle up and enjoy the ride.
Table Of Contents
What is a Subject?
RxJS is responsible for the reactivity in Angular. A Subject is a particular type of Observable from the RxJS library.
If you don't know what an Observable is, check this post by "Understanding RxJS Observables and why you need them" on the LogRocket blog.
An Observable is unicast. An Observer and its Subscriber have a one-to-one relationship. Each subscribed Observer owns an independent execution of the Observable.
In comparison to a regular Observable, a Subject allows values to be multicasted to many Observers. A Subject and its subscribers have a one-to-many relationship.
A Subject can be an Observable as well as an Observer. They hold a registry of many listeners to multiple Observables.
Observable VS Subject in Code
An Observable and Subject share their API. Both of them have the same methods and how you create them. But they behave very differently from each other.
Observable in Code
Here, you can see that the data is sent to the first subscriber and will finish before it continues to the next subscriber.
In the RxJS documentation, they are describing that "Each call to
observable.subscribetriggers its independent setup for that given subscriber".
That's why every subscriber is running independently from each other. But the RxJS team offers a way to create "multicasted Obsevables."
Subject in Code
With the Subject, you can see that the Subject takes the lead. It sends messages to both subscribers instead of waiting. In my opinion, this clearly shows the difference between a regular Observable and a Subject.
The RxJS documentation says the following about subscribing to a Subject.
Internally to the Subject, subscribe does not invoke a new execution that delivers values. It simply registers the given Observer in a list of Observers, similarly to how addListener usually works in other libraries and languages.
We know that a
Subject is an
Observable. But instead of sending information to one subscriber, they can send their data to multiple subscribers simultaneously (they multicast).
Subject has three methods which you can use.
subscribewith this method, you can activate the subscription of a new subscriber.
nextwith this method, you can pass new values. All the current subscribers will receive this.
completewith this method, you close all the subscriptions to the Subject.
A vital detail is that a Subject doesn't have an initial value. Every value passed with the
next method will send the values to all the subscribers.
But if the value is already sent before a subscriber is subscribed, it won't receive that data. (Click the "run" button to see it working)
BehaviourSubject is a variant of the
Subject. This variant knows about the current value, which a normal
When there has already been sent data to the current subscribers, this Subject becomes very useful. But another subscriber get's introduced at a later moment. Sometimes you want to pass the current value to that subscriber. With the
BehaviourSubject you can do that. (Click the "run" button to see it working)
So use the
BehaviourSubject to give a subscriber the last known value of the
Observable. But, what if you want a bit more than the previous value?
ReplaySubject does what it says. It can replay a fixed amount of values to new subscribers.
Think of an online playlist that a DJ is playing. But you want to go back in that stream. The
ReplaySubject can make sure you can revert three tracks and start listening from there. (Click the "run" button to see it working)
As you can see, at the creation of the
ReplaySubject(2), I passed the number 2, which tells the
Subject that it needs to send the last two values to every new subscriber.
When that new subscriber received the passed values, it will stay in sync with the other subscriber, which is excellent.
But to make sure that the
ReplaySubject(10000) won't pass constant values to every new subscriber, we can give it a time limit. The example below defines that it can keep a hundred values in memory and pass it to new subscribers, but those values are valid for 500 milliseconds.
const subject = new ReplaySubject(100, 500);
This feature gives a lot of possibilities, so be smart with it.
When I saw the
AsyncSubject and saw that it only sends the latest value to subscribers when it's completed, I thought, "why would I want to use this?". Until I saw this post on Medium.
So this gave an idea that an
AsyncSubject is a great candidate for Ajax requests. Because with most GET requests, you're only going to wait for one response, right.
When you click the "run" button above, you will see that the
AsyncSubject will pass multiple values, but only the last value before the
complete() method is called will give to the subscribers.
In most of the scenarios where you use a
Subject with subscribers, it's relevant that you get access to the value that has passed. But what if you don't need an actual value but only want to hook into the event and don't need a value. That's when you use a void subject.
The default behavior for a
Subject is just that. (Click the "run" button to see it working)
Let's wrap this up and conclude when you need a regular
Observable or one of the
Use a Observable when..
Observable should be used when you only need one subscriber. Or you don't care that the subscriber that comes first will be finished first until the second will get its values.
Use a Subject when..
When you need multiple subscribers and care that all the subscribers are getting their new values simultaneously, you need a
- Use a
BehaviourSubjectwhen you need the last given value.
- Use a
ReplaySubjectwhen you need more than the last given value. (For example, the previous five values) Or you want to set a time window for the values can be validly sent to subscribers.
- Use an
AsyncSubjectwhen you only want the last value to be passed to the subscribers.
- Use a Void
Subjectif you don't want to pass any value but just want to hook into the event.
Hopefully, this will help you make the right choice!
I hope you learned something new or are inspired to create something new after reading this story! 🤗 If so, consider subscribing via email (scroll to the top of this page) or follow me here on Hashnode.
Did you know that you can create a Developer blog like this one, yourself? It's entirely for free. 👍💰🎉🥳🔥
If I left you with questions or something to say as a response, scroll down and type me a message. Please send me a DM on Twitter @DevByRayRay when you want to keep it private. My DM's are always open 😁