user12251399
user12251399

Reputation:

Ngrx fetch data only if store is empty

Let's assume in my application I have 3 pages: Faculties,Groups,Specialities.

This is how interface for these entities looks like:

interface Faculty {
  faculty_id: number;
  faculty_name: string;
  faculty_description: string;
}
interface Speciality {
  speciality_id: number;
  speciality_code: string;
  speciality_name: string;
}
interface Group {
  group_id: number;
  group_name: string;
  speciality_id: number;
  faculty_id: number;
}

When I go to page Faculties in ngOnInit I'm checking boolean property in the FacultyState, If faculties has already been loaded then do not dispatch action else in Effect the service will make http request.

The same I've done for Speciality page.

Faculty component (Speciality also similar)

ngOnInit(): void {
        this.store.pipe(
          select(areFacultiesLoaded),
          tap((hasLoaded) => {
            if (!hasLoaded) {
              this.store.dispatch(loadAllFaculties())
            }
          })
        ).subscribe();
    
    
       this.faculties$ = this.store.pipe(select(selectAllFaculties))
      }

Effect

@Injectable()
export class FacultyEffects {
    loadFaculties$ = createEffect(() => {
        return this.actions$.pipe(
                ofType(FacultyAction.loadAllFaculties),
                concatMap(() => {
                   return this.apiService.getEntity('Faculty').pipe(
                        map(data => FacultyAction.allFacultiesLoaded({ faculties: data })),
                        catchError(() => EMPTY)
                        )}
                    ),
        );
    });

The problem

For example I can go to the group page first which also needs faculties and specialties.

  1. Should I again check If faculties and specialities have been loaded?
  2. Should I create another action for groups for example - [Groups page] fetch all Faculties(Specialities)
  3. Should I create another effects for those actions?

Upvotes: 1

Views: 1695

Answers (1)

timdeschryver
timdeschryver

Reputation: 15505

See https://timdeschryver.dev/blog/start-using-ngrx-effects-for-this#4-using-a-selector-inside-your-effects fore more info

@Effect()
getOrder = this.actions.pipe(
  ofType<GetOrder>(ActionTypes.GetOrder),
  withLatestFrom(action =>
    of(action).pipe(
      this.store.pipe(select(getOrders))
    )
  ),
  filter(([{payload}, orders]) => !!orders[payload.orderId])
  mergeMap([{payload}] => {
    ...
  })
)

Upvotes: 2

Related Questions