Kitty Quinn Thanks a lot for the response. 👍👏

You are right, it would be nice to get an object instead of an array. This would improve readability and Typesafety.

We can do it with scan. Although I am not sure if scan is the correct operator to use. The signature of scan is shown as following:

scan(accumulator: function, seed: any): Observable

Scan takes an accumulator function — so it basically combines together all emitted values.

In our case we are not interested in an accumulation but only in the comparison between the pervious and the current.

Comparison example

I created a small that tries to show the difference. Feel free to edit it, maybe you have some better solution 😉

Pairwise

const routeEvents = ['RouteEvent 1', 'RouteEvent 2', 'RouteEvent 3', 'RouteEvent 4', 'RouteEvent 5']from(routeEvents).pipe(
pairwise(),
map((values) => ({previous: values[0], current: values[1]}))
)
.subscribe(e => console.log(e))

Outputs:

Image for post
Image for post

Scan

const routeEvents = ['RouteEvent 1', 'RouteEvent 2', 'RouteEvent 3', 'RouteEvent 4', 'RouteEvent 5']from(routeEvents).pipe(
scan((acc: any, current: string) => {
return {
previous: acc.current || current,
current: current
}
}, {}))
)
.subscribe(e => console.log(e))

Outputs:

Image for post
Image for post

Scan also emits the first event so we could basically get rid of the startWith operator too.

I see your point with the object which is quite good. I would still prefer to use pairwise with an additional map function.

Using scan works but feels kind of using the wrong operator for our purpose.

Written by

Passionate freelance frontend engineer. ❤️ Always eager to learn, share and expand knowledge.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store