How to use ngrx’s combineReducers in Ahead-of-Time (AOT) Compiler?

Emily Xiong
1 min readFeb 25, 2019

--

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.

--

--

Emily Xiong
Emily Xiong

Written by Emily Xiong

A frontend web developer in Toronto

No responses yet