Search code examples
angularngrxngrx-storengrx-effects

Angualr componen't doesnt mount if effects return cached results


I'm trying to cache http requests to reduce traffic, in Task effect I'm checking if user tasks already retrieved. But when I do that, when I return cached tasks, component doesn't render. If you remove it and make http request again, it continue to work.

this is TasksEffect class

@Injectable()
export class TasksEffect {
  @Effect() fetchEffects = this.actions$.pipe(
    ofType(TaskListActions.FETCH_TASKS),
    withLatestFrom(this.store.select('tasksModule')),
    switchMap(([action, tasksModule]) => {
      if (tasksModule.tasks.length) {
        return of(new TaskListActions.SetTasks([...tasksModule.tasks]));
      }
      return this.taskService.fetchTasks((action as TaskListActions.FetchTasks).interval)
        .pipe(
          catchError(err => of(err)),
          switchMap(tasks => of(new TaskListActions.SetTasks(tasks))),
        );
    })
  );

  constructor(private taskService: TaskService, private store: Store<fromTasks.AppState>, private actions$: Actions) {
  }
}

Is there something wrong with my code ? if it so how can I fix it ? Also is there better approach to cache http request like memoize in react


Solution

  • In your code catchError(err => of(err)) should be after switchMap, because in case of an error the error will be reduced as TaskListActions.SetTasks.

    try like that, if it doesn't work - let me know in the comments. You need to check other places then, the effect is simple, perhaps this.taskService.fetchTasks has an issue.

    @Injectable()
    export class TasksEffect {
        @Effect() fetchEffects = this.actions$.pipe(
            ofType(TaskListActions.FETCH_TASKS),
            withLatestFrom(this.store.select('tasksModule')),
            switchMap(([action, tasksModule]) => {
                if (tasksModule.tasks && tasksModule.tasks.length) {
                    return of(new TaskListActions.SetTasks([...tasksModule.tasks]));
                }
                return this.taskService.fetchTasks((action as TaskListActions.FetchTasks).interval)
                    .pipe(
                        map(tasks => new TaskListActions.SetTasks(tasks)),
                        catchError(err => of(err)),
                    );
            })
        );
    
        constructor(private taskService: TaskService, private store: Store<fromTasks.AppState>, private actions$: Actions) {
        }
    }