One of my latest projects involved creating a versatile function that generates switch-case statements dynamically.
export function generateReducer(initialState, reducerName: ReducerName, adapter: EntityAdapter<any>): (state, initialState) => IState {
reducerName.plural = reducerName.plural ? reducerName.plural : reducerName.singular + 's';
return function (state = initialState, action: any): IState {
switch (action.type) {
case `[${reducerName.plural} Section] Load Statistics ${reducerName.singular}`:
case `[${reducerName.plural} Section] Load Details ${reducerName.singular}`:
case `[${reducerName.plural} Section] Load ${reducerName.plural}`:
{
return { ...state, loading: true, loaded: false };
}
...
}
and implementing it like this
export const adapter: EntityAdapter = createEntityAdapter();
export const initialState: State = adapter.getInitialState({
loaded: false,
loading: false,
selectedId: null
});
export const reducer = generateReducer(initialState, { singular: 'Skill' }, adapter);
While everything works smoothly when testing the project with ng-serve
(excluding AOT mode), encountering an error occurs when attempting to build for production using ng build --prod
:
ERROR in src\app\skills\skills.module.ts(46,45): Error during template compile of 'SkillsModule' Function calls are not supported in decorators but 'generateReducer' was called in 'reducers' 'reducers' references 'reducers' 'reducers' references 'reducer' at src\app\skills\store\reducers\index.ts(18,13) 'reducer' calls 'generateReducer' at src\app\skills\store\reducers\skills.reducer.ts(26,24).
I've explored various solutions to resolve this issue but it seems like I need to provide some form of indication to the compiler to recognize it as a compile-time function that produces code. Any suggestions on how to tackle this kind of challenge?
UPDATE:
I have included a stackblitz repository to showcase the error,
https://stackblitz.com/edit/reducer-factory-ngrx
Feel free to download the application, update the package.json devDependencies "@angular/cli": "^1.6.0", and test running 'ng build --prod'