Lessons44. scan as a reducer
Lessons · 44
44. scan as a reducer
The reducer pattern
Instead of "raw" numbers, you can use actions — objects that describe what happened. This is the core idea of Redux/NgRx, and it maps beautifully onto scan.
actions$.pipe(scan(reducer, initialState))
// reducer(state, action) → newState
Glossary
- Action — an object, usually with a
typefield, describing an event. - Reducer — a pure function
(state, action) => newState. - State — the current "snapshot" of the app's data.
The NgRx analogy
NgRx is built on the same scheme: dispatched actions → reducer → new state → subscribers. This lesson is a compact, teaching-sized version of that larger pattern.
Your task
- Inside the reducer, check
action.type: 'increment'→return { count: state.count + 1 }'decrement'→return { count: state.count - 1 }- Otherwise return
stateunchanged. - Important: don't mutate
state— return a new object. - Expected output:
Count: 1 → Count: 2 → Count: 1.
Solution spoiler · click to reveal
const { from, scan } = Rx;
const actions$ = from([
{ type: 'increment' },
{ type: 'increment' },
{ type: 'decrement' },
]);
const state$ = actions$.pipe(
scan((state, action) => {
if (action.type === 'increment') {
return { count: state.count + 1 };
}
if (action.type === 'decrement') {
return { count: state.count - 1 };
}
return state;
}, { count: 0 })
);
state$.subscribe(state => console.log('Count: ' + state.count)); script.ts
CONSOLE · Console output
Hit Run to see the result...