How to avoid unnecessary API call when working with NgRx

Viewed 144

I have an application with 2 menu item; Teams, Players. Whenever I toggle between them, I have to unnecessary api call even though I have the data in store.

Below is the effects file: //auth.effects.ts

loadTeams$ = createEffect(() => {
    return this.actions$.pipe(
      ofType(AuthActions.loadTeams),
      switchMap((action) =>
        this.apiService.teams$.pipe(
          tap(() => console.log('get teams request')),
          map((teams: Team[]) => AuthActions.loadTeamsSuccess({ teams })),
          catchError((error) => {
            console.log('err', error);
            return of(AuthActions.loadFailure({ error }));
          })
        )
      )
    );
  });

Below is the component from which I make api call

teams-list.component.ts

export class TeamsListComponent implements OnInit {
  loading$?: Observable<boolean>;
  error$?: Observable<string>;
  teams$?: Observable<Team[]>;
  retrySubject$ = new BehaviorSubject<boolean>(true);

  constructor(private store: Store<State>) {}

  ngOnInit(): void {
    this.store.dispatch(loadTeams());
    this.teams$ = this.store.select(getTeams);
    this.error$ = this.store.select(getError);
    this.loading$ = this.store.select(getLoading);
  }

  fetchRetry() {
    this.retrySubject$.next(false);
  }
}

This line in ngOnInit cause unnecessary api call. this.teams$ = this.store.select(getTeams);

How can I prevent it so that it makes the api call one time when initializing the app?

2 Answers
loadTeams$ = createEffect(() => {
    return this.actions$.pipe(
      ofType(AuthActions.loadTeams),
      // read the actions$ for an load success event
      withLatestFrom(this.actions$.pipe(ofType(AuthActions.loadTeamsSuccess)),
      // no success event? no teams loaded, so go on
      filter(([loadTeamsAction, loadTeamsSuccessAction]) => !loadTeamsSuccessAction),
      // remove unnecessary action
      map(([loadTeams,]) => loadTeams),
      switchMap((action) =>
        this.apiService.teams$.pipe(
          tap(() => console.log('get teams request')),
          map((teams: Team[]) => AuthActions.loadTeamsSuccess({ teams })),
          catchError((error) => {
            console.log('err', error);
            return of(AuthActions.loadFailure({ error }));
          })
        )
      )
    );
  });
Related