Subject & BehaviorSubject in Angular [RxJS]
While communication between components or retrieving data, We often use Observable. The first thing we do is define observable & subscribe it to get the data.
Now, What if data changes frequently or a certain function triggers to change the data.Observable doesn't notify its subscriber about its value changes. So, the subscriber in the components doesn't reflect any changes in the front-end.
Observable seems useless in cases where data changes need to be reflected in various components. So, in such case Subject & BehaviorSubject can be used to reflect the changes in all the component which it is subscribed to.
Subject
Subject is an observable which is also an observer and multicast meaning any changes in the Subject will be reflected automatically to every subscriber. Basically, Subject acts like a radio broadcast system which reflects all the program to all of its subscribers every time.
let subject = new Subject<string>();
subject.subscribe((data) => { //recieving data
console.log("incoming from one component : "+ data);
});
subject.subscribe((data) => {
console.log("incoming from another component : "+ data);
});
subject.next("Sending 1");// sending data
subject.next("Sending 2");
// Console result: incoming from one component: Sending 1
// Console result: incoming from another component: Sending 1
// Console result: incoming from one component: Sending 2
// Console result: incoming from another component: Sending 2
In the above example, we can see the use of next() method. next() method doesn't work for the regular observable but in the case of Subject, it is used for sending the data which is one of the benefits against the regular observable.
Similarly, multicasting is used i.e. use of multiple subscriptions for receiving data sent to the subject.
BehaviorSubject
BehaviorSubject is an exact copy of Subject. The only difference is an initial value must be provided while initializing the behavior subject and it provides the latest value right after subscription.
let subject = new BehaviorSubject<string>('sending initial data');
subject.subscribe((data) => {
console.log("incoming from one component : "+ data);
});
subject.subscribe((data) => {
console.log("incoming from another component : "+ data);
});// sending data
subject.next("Sending 1");
subject.next("Sending 2");
// Console result: incoming from one component: Sending initial data
// Console result: incoming from another component: Sending initial data
// Console result: incoming from one component: Sending 1
// Console result: incoming from another component: Sending 1
// Console result: incoming from one component: Sending 2
// Console result: incoming from another component: Sending 2
In the above example, right after the subscription, the initial value(latest value) is passed to the subscriber.
Here is an example where the sender component sends the change value from input to the receiver component using BehaviorSubject.
Service:
file name: observer.service.ts
dataSource is set as a BehaviorSubject with initial value 'Rohit Shrestha'.
setData function changes the value of the BehaviorSubject.
private dataSource = new BehaviorSubject<any>({name: 'Rohit Shrestha'});
data = this.dataSource.asObservable();
constructor() { }
setData(data) {
this.dataSource.next(data);
}
Two components:
Sender Component:
file name: sender.component.ts
the setName function is called to change the value of the BehaviorSubject.
setName(value) {
this.observerService.setData({name: value});
}
Receiver Component:
file name: receiver.component.ts
A subscription is made to listen to changes in the BehaviorSubject.
this.observerService.data.subscribe(
response => {
this.recievedData = response;
});
When to use Subject & BehaviorSubject?
We now clearly know the difference between Subject and BehaviorSubject. Subject on subscription doesn't provide any initial value while BehaviorSubject provides value on subscription. So, in the situation where you are confident that the initial value will be is something we use BehaviorSubject.
For example, let's take an example of a showing image on a user's profile. Upon unavailability of the image from the user, we need to show a default placeholder image. So, in such a case, we know a default value for the image is always a placeholder image. So, we use BehaviorSubject instead of Subject.
In case, where no image must be shown if the user doesn't upload any photo, Subject must be used.
Subject and BehaviorSubject helps us to reflect data changes in various component very easily. Thus, reducing the hassle of calling the same services with various other techniques.
Happy Coding!