Reputation: 1596
I'm new to ngrx
and I'm trying to have a state for each of my feature modules and also a state for app module. First, I registered StoreModule
and it's effects in app.module.ts
like this:
@NgModule({
declarations: [
...
],
imports: [
...,
StoreModule.forRoot({app: fromApp.reducer}),
EffectsModule.forRoot([AppEffectsService])
],
bootstrap: [AppComponent]
})
export class AppModule { }
Then I created a module called home with it's reducer and and effects service and used them like this:
@NgModule({
declarations: [
...
],
imports: [
...,
HomeRoutingModule,
StoreModule.forFeature(fromHome.homeFeatureKey, fromHome.reducer),
EffectsModule.forFeature([HomeEffectsService]),
]
})
export class HomeModule { }
I put a console.log
in my home reducer and saw every time I dispatch an action, I see the log twice per action! I don't now why my reducer is called twice per dispatch. And even when I add store to more modules, I see the repeated logs more.
The reducer looks like this:
const homeReducer = createReducer(
initialHomeState,
on(HomeActions.loadOrderTypesSuccess, (state, { orderTypes }) => ({ ...state, orderTypes })),
);
export function reducer(state: HomeState | undefined, action: Action) {
console.log(action.type);
return homeReducer(state, action);
}
And this is my effect:
loadOrderTypes$ = createEffect(() => this.actions$.pipe(
ofType(HomeActions.loadOrderTypes),
mergeMap(() => from(this.dataService.getOrderTypes())
.pipe(
map(orderTypes => HomeActions.loadOrderTypesSuccess({ orderTypes })),
catchError(error => of(HomeActions.loadOrderTypesFailure({ error }))),
)
)
));
The creation of actions:
export const loadOrderTypes = createAction(
'[Home Page] Load order type start'
);
export const loadOrderTypesSuccess = createAction(
'[Home Page] Load order type success',
props<{ orderTypes: OrderType[] }>()
);
export const loadOrderTypesFailure = createAction(
'[Home Page] Load order type failure',
props<{ error: any }>()
);
After dispatching the action, the log is:
@ngrx/store/init
15:23:36.470 app.reducer.ts:22 @ngrx/effects/init
15:23:36.505 core.js:38781 Angular is running in the development mode. Call enableProdMode() to enable the production mode.
15:23:36.608 app.reducer.ts:22 @ngrx/store/update-reducers
15:23:36.609 home.reducer.ts:35 @ngrx/store/update-reducers
15:23:36.644 app.reducer.ts:22 [Home Page] Load order type start
15:23:36.644 home.reducer.ts:35 [Home Page] Load order type start
15:23:36.761 client:52 [WDS] Live Reloading enabled.
15:23:37.743 app.reducer.ts:22 [Home Page] Load order type success
15:23:37.744 home.reducer.ts:35 [Home Page] Load order type success
I want my reducer to be called once. What am I doing wrong?
Upvotes: 4
Views: 2909
Reputation: 11
I was upgrading effects to v8 ngrx, and what called my issue, was in effects.
When deleted it @Effect()
, the problem was solved.
Bad:
@Effect()
test$ = createEffect(() => this.actions$.pipe(...
Good:
test$ = createEffect(() => this.actions$.pipe(...
Upvotes: 0
Reputation: 15487
An action is dispatched to all reducers, this is by design.
We can't know which reducers to call because it's perfectly fine to modify state based on an action from another module.
Upvotes: 2