I'm wondering if there is actually a proper use for behaviorSubject.value
. According to to this answer, we should ONLY get values via subscribing.
A case where it seems okay to me is where I'm using the .value
in order to determine the next value to push through the stream, like when I'm toggling a simple boolean:
myBoolSubject = new BehaviorSubject(false);
toggle() {
this.myBoolSubject.next(!this.myBoolSubject.value);
}
The alternative using subscribe()
would look like:
toggle() {
this.myBoolSubject.pipe(take(1)).subscribe(
val => this.myBoolSubject.next(!val)
);
}
From looking at the rxjs source and the aforementioned answer, the difference between these two approaches are that .value
will throw when:
- the subject has been completed
- there has been an error
In this simple case, I'm not going to complete the subject and I don't think errors are a concern since I'm just pushing simple boolean values through this subject.
Is this a valid use case for behaviorSubject.value
? Are there others?
Another case where it seems okay to use .value
is when constructing a new object from the previously emitted value:
private state = new BehaviorSubject<State>(INITIAL_STATE);
public state$ = this.state.asObservable();
public updateState(changes: Partial<State>){
const newState = {...this.state.value, ...changes};
this.state.next(newState);
}
The alternative would be to cache the latest state emission in another variable, something like this:
private _state = INITIAL_STATE;
private state = new BehaviorSubject<State>(INITIAL_STATE);
public state$ = this.state.asObservable();
public updateState(changes: Partial<State>){
const newState = {...this._state, ...changes};
this.state.next(this._state = newState);
}
Are there any concerns I'm overlooking?