How to use ngrx’s combineReducers in Ahead-of-Time (AOT) Compiler?
A problem I got: I got this angular app. I use ngrx’s combineReducers
function in some of my state reducers; however, I realize my app failed to build in the production environment.
This is what my setup looks like:
export function userId(state: string, action: SetUserId): string {
...
}
export function likedPostIds(state: Set<string>, action: any): Set<string> {
...
}
export const userReducer = combineReducers({ userId, likedPostIds });
This is what my root reducer looks like:
export const reducers: ActionReducerMap<AppState> = {
router: routerReducer,
language: languageReducer,
user: userReducer
};
This is how I set up the ngrx store in app.module:
StoreModule.forRoot(reducers, { metaReducers, initialState: initialAppState }),
The app runs fine locally. However, when I run ng build --prod
, it failed with below messages:
ERROR in app/app.module.ts(34,25): Error during template compile of 'AppModule'Function calls are not supported in decorators but 'combineReducers' was called in 'reducers''reducers' references 'userReducer' at app/store/app.reducer.ts(17,9)'userReducer' calls 'combineReducers' at app/store/user/user.reducer.ts(28,28).
So apparently combineReducers
does not work in AOT. What are some of the ways of getting around?
Use dependency injection: https://ngrx.io/guide/store/recipes/injecting.
export const REDUCER_TOKEN = new InjectionToken<ActionReducerMap<AppState>>('root reducer');@NgModule({
declarations: [...],
imports: [
...
StoreModule.forRoot(REDUCER_TOKEN, { metaReducers, initialState: initialAppState })
],
providers: [
{
provide: REDUCER_TOKEN,
useValue: reducers
},
]
})
I create an injection token named REDUCER_TOKEN
and provides the value with the root reducer I current have.
Now no more errors, my build runs fine in the production environment.