Manage State in RxJS with StartWith and Scan

John Lindquist
InstructorJohn Lindquist

Share this video with your friends

Send Tweet
Published 6 years ago
Updated 3 years ago

The scan operator in RxJS is the main key to managing values and states in your stream. Scan behaves just as a reduce function would, but scan is able to collect values from streams over time. This lesson covers using startWith to set the initial accumulator value then using scan to update the value of the clock from the clicks and interval.

[00:00] Since I want to control the clock, like move the time forward or backward or whatever, right now I'm just pushing a new date every five seconds or every time I click. What I need to do is actually track a date and then make changes to that date.

[00:16] When you think I need to track something in RxJS, think, I want to start with an initial value. That's the initial value is a new date. Every time some event comes through, I'm going to check for it and then change it. That new date is this accumulator, and then I can use the current, the thing that comes through, to change the accumulator however I want.

[00:42] To start with, I'm just going to return the accumulator to see what happens, and I need to go ahead and import start with, and import scan. Hit Save, refresh.

[01:00] You can see that it's going to give us one value, and no matter what I do, it's just going to return that same value. The clock is no longer updating, it's just set to that initial value. Every time, it's returning that same accumulated value.

[01:16] To be able to update this, I need to say that when something comes through, I want to grab a copy. We'll say date is, a new date. We'll just grab the accumulator, get the time, and then return that date.

[01:36] Since we have a copy of it, it's going to behave the exact same way, since it's just returning that copy. But what we can do is take that date and change it. I'll say date, set seconds, date, get seconds, and then add one.

[01:56] When I save and I refresh, you can see it starts with that initial date, and then every five seconds, it's going to update. It'll hit five and that updated to one second. When I click, it's going to move that forward and then five seconds, it pushed another value in here.

[02:13] I'll change this to one second so it looks more natural, refresh. You can see that every second, this is going to update. But I can also make it update even faster by clicking the button.

Fabio Biondi
Fabio Biondi
~ 5 years ago

Here my quick fix to the example:

.startWith(new Date().toString())


.scan((acc, action) => {
     let date = new Date(acc);
     switch (action) {
        case 'xyz':
           date.setSeconds(date.getSeconds() + 1);
     return date;
~ 4 years ago

can I pass initial new date to scan function without using startWith.