LiveLoveApp logo

Solution - BehaviorSubject

Solution

import { BehaviorSubject, fromEvent } from 'rxjs';
import { map, scan } from 'rxjs/operators';

/**
 * 1. Create a new BehaviorSubject, specify the generic type
 *    `number`, and set the seed value to `0`.
 */
const behaviorSubject = new BehaviorSubject<number>(0);

/**
 * 2. Use the `scan()` operator to sum the values emitted
 *    by the BehaviorSubject.
 *
 * 3. Subscribe to the BehaviorSubject and set the value
 *    property for the `sum` input.
 */
const sum = document.getElementById('sum') as HTMLInputElement;
behaviorSubject
  .pipe(scan<number, number>((prev, value) => prev + value, 0))
  .subscribe((value) => (sum.value = value.toString()));

/**
 * 4. Use the `fromEvent()` operator to add an event listener to
 *    both the `add` and `sub` button elements.
 *
 * 5. Use the `map()` operator to map the MouseEvent to either a
 *    positive 1 or a negative 1 for the add and subtract buttons
 *    respectively.
 *
 * 6. Subscribe to the event stream for both buttons  and set the
 *    Observer to the `BehaviorSubject` instance.
 */
const add = document.getElementById('add') as HTMLButtonElement;
const sub = document.getElementById('sub') as HTMLButtonElement;
fromEvent(add, 'click')
  .pipe(map(() => 1))
  .subscribe(behaviorSubject);
fromEvent(sub, 'click')
  .pipe(map(() => -1))
  .subscribe(behaviorSubject);

Let's review the solution code above:

  • First, we create a new BehaviorSubject, set the generic type to number, and set the seed value to 0.
  • The sum constant is the HTMLInputElement that will display the sum for our simply calculator.
  • We use the scan() operator to accumulate/sum the values emitted by the behaviorSubject inside of the pipe() method, and then subscribe() to the next notifications, setting the value property for the sum input element to the value emitted.
  • The add and subtract constants each reference the HTMLButtonElement in the DOM.
  • Using the fromEvent() operator we add an event listener for the click event on both buttons. Inside the pipe() method we use the map() operator to map the event to either 1 or -1. Finally, we subscribe to each click event Observable stream and set our behaviorSubject as the Observer.