简体   繁体   中英

Angular 5 - Function that return another Dynamic Function

I've created a function that generates a dynamic switch-case function statement.

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 using 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);

when running the project with ng-serve (not AOT) everything works fine, when trying to build for production using ng build --prod I get the following error

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).

tried to find any way to resolve this, but It seems that I need to provide this to the compiler somehow so he can tell its a compile time function that generates code. any ideas on how to manage with this kind of problem?

EDIT:

added a stackblitz repo to show the error,

https://stackblitz.com/edit/reducer-factory-ngrx

download the application, update the package.json devDependencies "@angular/cli": "^1.6.0", and try to run 'ng build --prod'

Try to add at "reducer.ts":

  export const reducer = generateReducer(initialState, { singular: 'Skill' }, adapter);

import { ActionReducerMap } from '@ngrx/store';
import { InjectionToken } from '@angular/core';

 // register reducer token
 export const reducerToken = new InjectionToken<ActionReducerMap<State>>(
   'Registered Reducers'
 );
 Object.assign(reducerToken, reducer);

 export function getReducers() {
   return reducer;
 }

and at the app.module.ts:

import { reducerToken, getReducers } from './reducer';


@NgModule({
imports: [
    BrowserModule,
    FormsModule,
    StoreModule.forRoot(reducerToken)
 ],
 declarations: [AppComponent, HelloComponent],
 providers: [
  {
    provide: reducerToken,
    useFactory: getReducers
  }
 ],
 bootstrap: [AppComponent]
})

This way it worked for me... Hope it helps

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM