Published
Edited
May 9, 2019
Insert cell
Insert cell
viewof Counter = {
const { BehaviorSubject } = Rx;
const { fromEvent } = Rx.Observable;
const { map, scan } = Rx.operators;

// HTML.
const view = html`
<button id="dec">-</button>
<span id="count">0</span>
<button id="inc">+</button>
`;

// Elements.
const decButton = view.querySelector('#dec');
const count = view.querySelector('#count');
const incButton = view.querySelector('#inc');

// Create an initial BehaviorSubject that our reducer$ subscribes to for it's action$.
// Upon subscription BehaviorSubject sends 'INIT'.
const action$ = new BehaviorSubject('INIT');

// Map increment button clicks to BehaviorSubject action$.
const inc$ = fromEvent(incButton, 'click')
.pipe(
map(() => 'INC')
)
.subscribe(action$);

// Map decrement button clicks to BehaviorSubject action$.
const dec$ = fromEvent(decButton, 'click')
.pipe(
map(() => 'DEC')
)
.subscribe(action$);

// Use scan() to reduce and emit new state we get from the BehaviorSubject action$.
const reducer$ = action$.pipe(
scan((state, actionType) => {
switch (actionType) {
case 'INC':
return state + 1;
case 'DEC':
return state - 1;
case 'INIT':
return 0;
default:
return state;
}
}, 0),
);

// Subscribe to BehaviorSubject action$ after they are scanned and update the count.
reducer$.subscribe(
state => count.innerText = state
);

return view;
}
Insert cell
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more