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!!
The BehaviorSubject There are two ways to get this last emited value. You can either get the value by accessing the . value property on the BehaviorSubject or you can subscribe to it. If you subscribe to it, the BehaviorSubject will directly emit the current value to the subscriber.
BehaviorSubject works in the following way: Create an internal subscriptions container. Set the current value kept by the subject to the initial value passed as an argument during instantiation. When a new subscription occurs, add it to the container and emit the current value to the corresponding observer.
Observable is a Generic, and BehaviorSubject is technically a sub-type of Observable because BehaviorSubject is an observable with specific qualities. An observable can be created from both Subject and BehaviorSubject using subject.
When a new subscriber subscribes to the ReplaySubject instance, it will synchronously emit all values in its buffer in a First-In-First-Out (FIFO) manner. The ReplaySubject will also complete, if it has observed completion; and it will error if it has observed an error.
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;
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With