RxJS Mastery – #36 scan

RxJS lesson title scan

The RxJS scan operator applies a reducer function to each value emitted by the source. This allows to continuously update and emit state. The operator offers an optional seed value:

scan<V, A, S>(accumulator: (acc: V | A | S, value: V, index: number) => A, seed?: S): OperatorFunction<V, V | A>

If that seed value is not defined the first emitted value is taken as “seed”.

Sum the numbers from the source

Setting the seed to 0 and calculating a sum in the reducer function allows us to sum up the arriving numbers and emit the result after each new source value:

of(1,2,3,4).pipe(
    scan((acc, curr) => acc + curr, 0)
).subscribe(console.log);

// 1
// 3
// 6
// 10

RxJS scan works also without seed value

The same result as seen above can be achieved by omitting the seed value. In this case the first source value, here 1, is used to initialise the state:

of(1,2,3,4).pipe(
    scan((acc, curr) => acc + curr)
).subscribe(console.log);

// 1
// 3
// 6
// 10

Always emit the highest value

The RxJS scan operator allows to check the newest value against the current. Thanks to that we can keep track of the current maximum:

of(1,15,7,3,20,2).pipe(
    scan((acc, curr) => acc > curr ? acc : curr)
).subscribe(console.log);

// 1
// 15
// 15
// 15
// 20
// 20

Exercise for the RxJS scan operator 💪

Implement Fibonacci with scan and interval. You can limit the output to 7 numbers, e.g. by using take(7). To simplify it you can start with 1, 2, 3, 5…

As always the code examples and exercise solution can be found on GitHub.