BehaviorSubject
BehaviorSubject
The BehaviorSubject
class extends the Subject
class, which extends the Observable
class.
Let's break down the behaviors (pun intended) of the BehaviorSubject
:
- The
BehaviorSubject
requires an initial seed value. - An Observer always receives the last next notification emitted (or the seed value).
- An Observer receives all next notification until unsubscribing, or until the Observable completes or errors.
- Once the
BehaviorSubject
is complete any new Observers will receive the last next notification and the complete notification in the same frame. - When the
BehaviorSubject
emits an error notification, all Observers receive the error notification, including those Observers that subscribed after the error notification.
Example
Let's take a look at an example using the BehaviorSubject
:
import { BehaviorSubject } from "rxjs/BehaviorSubject";
/* Create an instance of BehaviorSubject. */
const behaviorSubject = new BehaviorSubject<number>(0);
/* Subscribe to subject. */
behaviorSubject.subscribe({
next: (value) => console.log('before:', value),
error: (error) => console.error('before', error),
complete: () => console.log('complete before')
});
/* Emit some values. */
behaviorSubject.next(1);
behaviorSubject.next(2);
behaviorSubject.next(3);
/* Subscribe late to subject. */
behaviorSubject.subscribe({
next: (value) => console.log('after:', value),
error: (error) => console.error('after:', error),
complete: () => console.log('complete after')
});
Let's go through this example and look at each block of code:
- First, we create a new instance of the
BehaviorSubject
class, specify the generic type ofnumber
, and provide the seed value of0
. - We subscribe to the
BehaviorSubject
. At this point we have not used thenext()
method on theBehaviorSubject
to emit next notifications to Observers. - Then, we emit three values using the
next()
method. Note, the last value emitted was the number3
. - Finally, we add a new Observer.
What next notification values will the first Observer receive?
The first Observer will receive the following next notifications:
- frame 0: the value
0
. - frame 1: the value
1
. - frame 2: the value
2
. - frame 3: the value
3
.
What next notification values will the second Observer receive?
The second Observer will receive the following next notifications:
- frame 0: the value
3
.
Example with Completion
Let's take our previous example and change it slightly.
Let's complete()
the Observable before the second Observer.
import { BehaviorSubject } from 'rxjs';
/* Create an instance of BehaviorSubject. */
const behaviorSubject = new BehaviorSubject<number>(0);
/* Subscribe to subject. */
behaviorSubject.subscribe({
next: (value) => console.log('before:', value),
error: (error) => console.error('before', error),
complete: () => console.log('complete before')
});
/* Emit some values. */
behaviorSubject.next(1);
behaviorSubject.next(2);
behaviorSubject.next(3);
// behaviorSubject.error(new Error());
behaviorSubject.complete();
/* Subscribe late to subject. */
behaviorSubject.subscribe({
next: (value) => console.log('after:', value),
error: (error) => console.error('after:', error),
complete: () => console.log('complete after')
});
What notifications will each of our Observers receive?
Let's break this down by frame:
| Frame | First Observer | Second Observer |
|-------|-----------------|------------------|
| 0 | next: 0
| complete |
| 1 | next: 1
| |
| 2 | next: 2
| |
| 3 | next: 3
| |
| 4 | complete | |
As we can see in the breakdown above, the second Observer never receives a next notification. Rather, the second Observer only receives the completion notification.
Bonus
As a quick bonus, try changing the complete()
to the error()
method on the BehaviorSubject
.
I added this to the code above and commented it out.