angularngrxajax-pollingngrx-effects

Ngrx Store, Effects, Http Ajax Polling Setup on Angular 2


I'm creating an Ngrx Angular 2 app and was trying to get my http calls to continue polling after a time interval. I have seen the use of the interval() function, but in case of Ngrx, when service calls are done inside @Effect(), it gives an error. Please advise:

@Injectable()
export class TasksEffects {
constructor(
    private actions$: Actions,
    private TS: TaskService
){}

@Effect()
onLoadTasksLoadTasks$: Observable<Action> = this.actions$.ofType(tasksActions.ActionTypes.LOAD_TASKS)
    .switchMap(() => {
        return this.TS.index()
            .map((res) => new tasksActions.LoadTasksSuccessAction(res.json()))
            .catch(err => of(new tasksActions.LoadTasksFailAction(err)));
    });

I want to run the switchMap function every ten seconds. This does not work.

    @Effect()
onLoadTasksLoadTasks$: Observable<Action> = this.actions$.ofType(tasksActions.ActionTypes.LOAD_TASKS)
    .switchMap(() => {
        return this.TS.index()
            .map((res) => new tasksActions.LoadTasksSuccessAction(res.json()))
            .catch(err => of(new tasksActions.LoadTasksFailAction(err)));
    }).interval(10000);

The type error is:

enter image description here


Solution

  • As stated in the other answer, interval is a static function, so it does not exist on the Observable prototype - which is why your error is effected.

    Instead, you should be able to achieve what you want using timer.

    import { Observable } from 'rxjs/Observable';
    import 'rxjs/add/observable/of';
    import 'rxjs/add/observable/timer';
    import 'rxjs/add/operator/catch';
    import 'rxjs/add/operator/map';
    import 'rxjs/add/operator/switchMap';
    
    @Effect()
    onLoadTasksLoadTasks$: Observable<Action> = this.actions$
      .ofType(tasksActions.ActionTypes.LOAD_TASKS)
      .switchMap(() => Observable
        .timer(0, 10000)
        .switchMap(() => this.TS.index()
          .map((res) => new tasksActions.LoadTasksSuccessAction(res.json()))
          .catch(err => Observable.of(new tasksActions.LoadTasksFailAction(err)))
        )
      );
    

    With timer, it's possible to specify an initial delay and here it's set to zero so that the timer fires immediately. After that, it will fire every ten seconds, but if another LOAD_TASKS action is received, the switchMap will see it unsubscribed and a new timer created, etc.