Behaviorsubject vs Subject rxjs - What to Use?
Behaviorsubject vs Subject rxjs - What to Use?

In this post you will learn the difference between Behaviorsubject and just Subject inside RxJS.

Subject is a really powerful tool inside RxJS. But in order to understand the usages of it let's create both Subject and Behaviorsubject.

Behaviorsubject

Here I want to create a Behaviorsubject and store a list of users inside.

interface UserInterface {
  id: string;
  name: string;
}

users$ = new BehaviorSubject<UserInterface[]>([]);

Here we defined BehaviorSubject users which the data type UserInterface[] and we must set a default value. In our case it is an empty array.

In BehaviorSubject it is a must to provide initial value.

BehaviorSubject is extremely powerful because we can use it as an observable but we can also set new values inside. Which means we can update it from any place.

ngOnInit(): void {
  this.users$.subscribe((users) => {
    console.log('users', users);
  });
}

We will see a single console.log in browser because when we set a default value all subscribers of our BehaviorSubject are notified about it.

But at some point we want to update our BehaviorSubject. For example when we got users from the API.

ngOnInit(): void {
  this.users$.subscribe((users) => {
    console.log('users', users);
  });

  setTimeout(() => {
    this.users$.next([{ id: '1', name: 'Foo' }]);
  }, 2000);
}

I used setTimeout to simulated the long API call and inside called next which is used to update a value inside stream.

You can update BehaviorSubject from any place by using next function.

Next

As you can see our array was updated after 2 seconds.

Which essentially means that BehaviorSubject is a perfect solution to store some state where you can subscribe to it from any place but also you can trigger changes to this state.

But it is not all, we have even more. At any moment of the time we can read what is inside our BehaviorSubject.

setTimeout(() => {
  this.users$.next([{ id: '1', name: 'Foo' }]);
  console.log('setTimeout', this.users$.getValue());
}, 2000);

By using getValue function we can get current value at any moment. If you worked with observables previously you know how difficult it is to get a value of the observable with some event handlers. With BehaviorSubject you don't have such problem.

Subject

In 99% of Subject cases we are using BehaviorSubject. But now let's compare it with just plain Subject.

export class AppComponent implements OnInit {
  ...
  subject$ = new Subject<UserInterface[]>();

  ngOnInit(): void {
    ...
    this.subject$.subscribe((users) => {
      console.log('users from subject', users);
    });

    setTimeout(() => {
      this.subject$.next([{ id: '1', name: 'Foo' }]);
    }, 2000);
  }
}

Here we created Subject and the only difference is that we didn't provide the initial value to it. We still have subscribe and next functions.

The main difference is that we won't have initial value and our listeners won't be notified.

The second major difference is the Subject doesn't store a value inside. This is why getValue function simply doesn't exist. So you can't read the value at any moment like you can with BehaviorSubject.

And actually if you want to improve your Angular knowledge and prepare for the interview I highly recommend you to check my course Angular Interview Questions - Coding Interview 2023.

📚 Source code of what we've done