6

I am working on a project in which portions of the code-base are using BehaviorSubject quite liberally. In most cases being used when there is no initial state, or a need to have an initial value outside of the first explicit "onNext/emit".

I am having a hard time determining if there is any downside to this? Also if not, why wouldn't everyone just always use BehaviorSubject (even constructed without a parameter) as opposed to a standard Subject?

Thanks in advance!

iHazCode
  • 622
  • 4
  • 15
  • 3
    Why ever use for when you can do everything using while? Why use Python when you can write C? Why take the car to work when you can use the bus? – Ingo Bürk Mar 27 '18 at 05:11
  • One such example for when to use `Subject` is when you open a pop-up and listen to mouse click event to hide said pop-up. You don't want to catch the last mouse-event just to discard it, but rather wait for the next. – Harry Ninh Mar 27 '18 at 05:20
  • I understand what you're saying, but outside of the fact that it takes an initial value I wasn't sure the implications of using BehaviorSubject over a subject. Also like I said , the project I'm working on it seems BehaviorSubject is being used exclusively due to the additional benefit I previously mentioned. Therefor I was trying to learn more about the type so I could better distinguish when it's better to "use the car instead of taking the bus" ;) – iHazCode Mar 27 '18 at 05:20

2 Answers2

8

A BehaviorSubject is quite different from a Subject other than the initial value: it also acts like a ReplaySubject(1). This means that new subscribers will always get the last (or initial) value emitted synchronously. With a Subject, you only get the emissions that happen after you subscribed.

Hence, if you want to, say, store data in a service, a BehaviorSubject is typically a good choice. A Subject on the other hand might be better suited to emit events to subscribers.

In other words, use a Subject when you don't care about the past ever.


As far as the initial value goes, regardless of those effects: if you don't need one, don't use one. Why? Because. I mean you can also always write

var x;
x = 5;

instead of

var x = 5;

But... why would you?

Don't emit events that the subscriber needs to put effort into ignoring. A typical Angular case is using a Subject which you emit + complete in ngOnDestroy so you can use takeUntil to limit subscriptions in the component. If it was a BehaviorSubject, it just wouldn't work.

Ingo Bürk
  • 19,263
  • 6
  • 66
  • 100
  • Thank you, this was very helpful. Not sure why I was unable to deduce this from the other reading I did, but this will be helpful for me going forward in distinguishing which to use. Thanks again! – iHazCode Mar 27 '18 at 05:22
1

It's important to respect the original principle behind both kinds of Subjects. As in most cases, every choice should be determined by the context. Some good initial questions would be as follows:

  1. Do I have an initial state for my stream?
  2. Do I need a quick and easy Observable/Observer engine?
  3. Do I really need only one object that manages "next/complete/error" and subscription?
  4. Does the subscriber need to receive the last item emitted?

These are always good types of questions to ask to help you to decide what kind of Subject to use.

Yanis-git
  • 7,737
  • 3
  • 24
  • 41