0
votes

I am trying my best to enable my ngrx effects conditionally call itself every 2 seconds in following way using timer:

  @Effect()
  loadSummary$ = this.actions$
  .pipe(
    
    ofType(SummaryTypes.SAVE_SUMMARY),
    
    switchMap((action:any) => (action.running ? timer(0, 2000) : NEVER)),
    
    switchMap((action: any) => {

      console.log(action); /* prints 0 (how is this possible?!) */

      return this.analyticsService.getData(action.fetchArr, action.startAndEndDate).pipe(
        catchError((err) => {
          /* log error */
        }),
      )
    }),
  ) 

So I am calling second switchMap after every 2 seconds. action.running also correctly returns true or false in first switchMap call, however, the console.log(action) returns 0 and similarly, action.fetchArr and action.startAndDate returns undefined.

This is because i am not able to return first action to second action as is. Could someone guide me to what am I doing wrong?

What I want:

I want my effect to call itself every 2 seconds and if action.running returns false then it must immediately stop. console.log(action); should correctly return the passed object in second switchMap and not 0.

What I tried:

Tried reading about effects from last few hours and even tried using takeUntil but not able to find any particular way.

2

2 Answers

1
votes

Hi I tried somthing like this and worked

  public someSubject = new Subject<boolean>();
  public someObes = from([1, 2, 3, 4]);

  ngOnInit() {
    this.someSubject
      .pipe(
        switchMap(
          (value: boolean): any =>
            timer(0, 200).pipe(
              filter(() => value),
              switchMap((): any => this.someObes)
            )
        )
      )
      .subscribe(value => console.log(value));

    this.someSubject.next(true);

    setTimeout(() => this.someSubject.next(false), 3 * 1000);

    setTimeout(() => this.someSubject.next(true), 5 * 1000);

    setTimeout(() => this.someSubject.next(false), 8 * 1000);
  }
}

I think that you should pipe the timer(0, 2000)

1
votes

To actually address your misunderstanding: .console.log(action); /* prints 0 (how is this possible?!) */ In the switchMap before this step, you are switching to the timer observable and that returns a running number. Check the type of action there. It is just not what you expect it to be.

I think this should do the trick:

  switchMap((action: any) =>
        (action.running ? timer(0, 2000) : NEVER)
          .pipe(map(() => action))),
      switchMap((action: any) => { // now this is actually of type 'Action'
        console.log(action);