Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Best way to read and update a value of a BehaviorSubject

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!!

like image 866
user2010955 Avatar asked Jul 23 '18 08:07

user2010955


People also ask

How do I access values in BehaviorSubject?

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.

How do you complete a BehaviorSubject?

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.

What is the difference between BehaviorSubject vs observable?

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.

How do you replay a 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.


1 Answers

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;
    }
}
like image 120
madjaoue Avatar answered Sep 28 '22 08:09

madjaoue