Search code examples
javascriptrxjsrxjs6

RxJS- How to access the value of a BehaviorSubject after operations


Say I have a behavior subject, piped through an operation or two:

const inputNumber = new BehaviorSubject(2);

// The current number can be retrieved with `inputNumber.getValue()`

const numberAfterOperations = inputNumber.pipe(
  filter(a => (a+1) % 2), // filter out odd numbers
  map(a => a * a), // square it
);

How can I access the value of numberAfterOperations?

// Does not work because `getValue` is not defined!
numberAfterOperations.getValue(); // I expect this to be 4

inputNumber.next(4);

// Does not work!
numberAfterOperations.getValue(); // I expect this to be 16

Note: the observable subscription here works fine. I'm asking about synchronous access to the .value (or .getValue())

I noticed a similar issue here, but did not see a resolution: https://github.com/ReactiveX/rxjs/issues/2378


Solution

  • Thanks for the answers, folks. You have helped me realize that there is no built-in way to do what I wanted with behavior subjects. I wound up with the following:

    function mapBehaviorSubject(behavior, mapFn) {
      const mappedSubject = new BehaviorSubject(mapFn(behavior.getValue()));
      behavior.subscribe({
        next: value => mappedSubject.next(mapFn(value)),
      });
      return mappedSubject;
    }
    

    This allows me to have the desired behavior:

    const inputNumber = new BehaviorSubject(2);
    
    const numberAfterOperations = mapBehaviorSubject(inputNumber, x => x * x);
    

    This allows me to have a persistent subject with the mapped value available synchronously with getValue().