LiveLoveApp logo

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')
});

See example on codesandbox

Let's go through this example and look at each block of code:

  1. First, we create a new instance of the BehaviorSubject class, specify the generic type of number, and provide the seed value of 0.
  2. We subscribe to the BehaviorSubject. At this point we have not used the next() method on the BehaviorSubject to emit next notifications to Observers.
  3. Then, we emit three values using the next() method. Note, the last value emitted was the number 3.
  4. 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.