Reputation:
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.
ngOnInit(): void {
this.store.pipe(
select(areFacultiesLoaded),
tap((hasLoaded) => {
if (!hasLoaded) {
this.store.dispatch(loadAllFaculties())
}
})
).subscribe();
this.faculties$ = this.store.pipe(select(selectAllFaculties))
}
@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)
)}
),
);
});
For example I can go to the group page first which also needs faculties and specialties.
Upvotes: 1
Views: 1695
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