The ability to reply to discussions is limited to PRO members. Want to join in the discussion? Click here to subscribe now.

Managing State in RxJS with StartWith and Scan

Managing State in RxJS with StartWith and Scan

2:23
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.
Watch this lesson now
Avatar
egghead.io

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.

Avatar
Randy

I had an issue with the accumulator.

const date = new Date(acc.getTime());
When transpiling, I got a typescript error:

Property 'getTime' does not exist on type '{}'.

While searching online I found some people having the same issue with not declaring a type.
I solved it by creating a new variable with type 'any' and assigned the value of the acc (accumulator) to it.
let acc2:any= acc;
const date = new Date(acc2.getTime());

I have a feeling that this isn't the best solution but I couldn't figure how to get the correct type to apply to acc2.

In reply to egghead.io
Avatar
Goma Games

i got it to work by setting the type of acc to Date
without setting the type, i get this compile time error

Operator '+' cannot be applied to types 'Object' and 'number'.
export class ClockComponent {
  public click$ = new Subject();
  public clock:Observable<Date>;

  constructor(){
    this.clock = Observable
    .merge(
      this.click$,
      Observable.interval(5000)
    )
    .startWith(new Date())
    .scan((acc:Date, curr)=> new Date(acc.getTime()+1000) );
  }

}

hth

In reply to Randy
Avatar
Fabio Biondi

Here my quick fix to the example:

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

and

.scan((acc, action) => {
     let date = new Date(acc);
     switch (action) {
        case 'xyz':
           date.setSeconds(date.getSeconds() + 1);
           ...
     }
     return date;
Avatar
Anzumana

great solution. thanks

In reply to Goma Games
HEY, QUICK QUESTION!
Joel's Head
Why are we asking?