since it's well known that use getValue() method on a BehaviorSubject should be avoided link I'm wondering what's the best way to read and updated a BehaviorSubject.
In my case I've a BehaviorSubject storing an array of objects and when I click on a button I should push another object to the array and emit the new value to all the subscribers.
Right now I'm doing:
this.myBehaviorSubject.next([
...this.myBehaviorSubject.value,
{ new object }
])
Is there a better approach?
Thanks!!
Imperative is not good or bad, it depends on how you use it.
Publish
use next
method. Here's what it looks under the hood :
// update this._value and call Subject's next method
next(value: T): void {
super.next(this._value = value);
}
// Subject's next method
next(value?: T) {
if (this.closed) {
throw new ObjectUnsubscribedError();
}
if (!this.isStopped) {
const { observers } = this;
const len = observers.length;
const copy = observers.slice();
for (let i = 0; i < len; i++) {
copy[i].next(value);
}
}
}
It's difficult to be more straightforward if you want to update the current value and send it to observers.
Get the current Value
The natural way to get values from any Observable is to subscribe to it. In most cases, getValue
is really a bad idea because, in most cases, Observables are chained, used asynchronously. For example, if you want to merge or zip the values of two subscribers, the way to go is :
zip(Subject_1, myBehaviorSubject).subscribe( val=> console.log(val));
Now, in some cases, you just need to access the current value, synchronously, and without chaining operators. In this case, use getValue
. Under the hood :
getValue(): T {
if (this.hasError) {
throw this.thrownError;
} else if (this.closed) {
throw new ObjectUnsubscribedError();
} else {
return this._value;
}
}