Reputation: 73
Problem Description I have a spinner module, which is displayed/hidden based on a loading property in my root state. This is placed inside AppComponent.
export interface AppState {
loading: boolean
}
I have multiple lazily loaded feature modules, each of which fetch data through their own set of effects. While doing this, I would like to update the AppState.loading to true at the beginning of the effect and then set it back to false when the effect completes.
How do I do this?
Work-around As a work-around, I am dispatching an action defined in root actions (which sets loading to true) before triggering my feature action, and then the feature effect returns an array of actions. One of these actions again belongs to root actions (which sets loading to false).
service.ts
public getMilestonesAction(q: string) {
this.store.dispatch(AppActions.loadingAction({ loading: true})); // This belongs to root-actions
return this.store.dispatch(CalendarActions.getEntriesAction({ q })); // This belongs to feature-actions
}
effect.ts
getMilestonesEffect$ = createEffect(() => this.action$
.pipe(
ofType(CalendarActions.getEntriesAction),
mergeMap(action => this.calendarService.getMilestones(action.q)
.pipe(
switchMap((data: Milestone[]) => [AppActions.loadingAction({ loading: false }), CalendarActions.getEntriesSuccessAction({ milestones: data })]),
catchError((error: any) => from([AppActions.loadingAction({ loading: false }), CalendarActions.getEntriesFailureAction( { error: this.getErrorMessage(error) })]))
))
));
Is this the correct approach to this problem?
Upvotes: 1
Views: 988
Reputation: 13539
That is correct and you do it right.
root
and feature
only allows you to lazy load reducers and effects for modules that need them, but both of them have full access to the store and can use actions they need.
Angular recommends to have core/feature/shared
groups of modules. In this case, the load action would be in core
or shared
, what you feel is the better fit.
Upvotes: 2