I am migrating my Angular application, v20, which uses ng/rx store from module based to standalone.
I had chosen to use classes for most of my reducers. For example, I have a reducer as follows
@Injectable({ providedIn: 'root' }) export class AppReducer { private readonly initialState: AppState = { networkTestModeEnabled: false, networkTestOnline: true }; /** * Reducer function */ public reduce = createReducer( this.initialState, on(appActions.setTestNetworkMode, (state, { testModeEnabled }): AppState => ({ ...state, networkTestModeEnabled: testModeEnabled })), on(appActions.setTestNetworkOnline, (state, { isOnline }): AppState => ({ ...state, networkTestOnline: isOnline })), ); } And in my app.module.ts I could use this via an InjectionToken...
export const APP_REDUCER_TOKEN = new InjectionToken<ActionReducer<Map<string, AppState>>>('App reducer'); export function appReducerFactory(reducer: AppReducer): (state: AppState, action: Action) => AppState { return (s, a) => reducer.reduce(s, a); } And then in the module have a setup like the following...
StoreModule.forRoot({}), EffectsModule.forRoot([]), StoreModule.forFeature(Constants.vals.featureNames.appState, APP_REDUCER_TOKEN), StoreModule.forFeature(Constants.vals.featureNames.globalfeature1, F1_TOKEN), EffectsModule.forFeature([ AppEffects, F1Effects, .. etc ]), { provide: APP_REDUCER_TOKEN, deps: [AppReducer], useFactory: appReducerFactory, }, Now going to standalone, in my main.ts, I see I should be using the provideStore, provideEffects and provideState, so I have...
bootstrapApplication(AppComponent, { providers: [ provideStore(), provideEffects([AppEffects, F1Effects]), provideState({ name: Constants.vals.featureNames.appState, reducer: APP_REDUCER_TOKEN, }), provideState({ name: Constants.vals.featureNames.F1, reducer: F1_REDUCER_TOKEN, }), However, I am getting the following error for the line
provideState({ name: Constants.vals.featureNames.appState, reducer: APP_REDUCER_TOKEN, }), I have another reducer that is NOT a class, and not using an InjectionToken, and this is accepted, but not where I use the token.
My question is, how do I now setup a reducer that is defined as a class? Do we still use an InjectionToken, and/or if so, how do I use this with provideState?
[UPDATE1]
Unfortunately using @Naren Murali method I get the error...
app-events.effects.ts:164 ERROR RuntimeError: NG0203: The `AppReducer` token injection failed. `inject()` function must be called from an injection context such as a constructor, a factory function, a field initializer, or a function used with `runInInjectionContext`. Find more at https://angular.dev/errors/NG0203 at reducer (app.config.ts:92:31) This is weird as the app-events.effects,ts is not even for the AppReducer. it is for a different feature. My AppState does not have any effects (but other slices do)
i.e I also have
provideEffects([CurrentDayEffects, AppEventsEffects]), etc
