I have 3 objects implementing 3 different interfaces that I'm managing theirs states with ngrx (latest versions). The reducers are defined as: loginReducer, PrsnlReducer and userReducer. I'm handling the PrsnlReducer and the userReducer as ngrx entities because I want to take advantage of the ngrx entity build-in actions, and I handle the loginReducer with basic reducer concept (Not as an entity). These are the three:
loginReducer.ts
const initialState: AuthStateInterface = {
isSubmitting: false,
user_code: '',
token: '',
userId : '',
}
const logReducer = createReducer(
initialState,
on(loginAction,
(state: AuthStateInterface): AuthStateInterface => ({
...state,
isSubmitting: true
}))))
export function loginReducers( state: AuthStateInterface, action: Action){
return logReducer(state, action)
}
userReducer.ts
export interface State extends EntityState<userStateInterface> {
}
export const adapter: EntityAdapter<userStateInterface> = createEntityAdapter<userStateInterface>();
export const initialState: State = adapter.getInitialState({
});
const usrReducer = createReducer(
initialState,
on(UserActions.addUser, (state, { user }) => {
return adapter.addOne(user, state)
}),
on(UserActions.setUser, (state, { user }) => {
return adapter.setOne(user, state)
})
);
export function userReducer(state: State | undefined, action: Action) {
return usrReducer(state, action);
}
PrsnlReducer.ts
export interface State extends EntityState<prsnlStateInterface > {
// additional entities state properties
selectedUserId: number | null;
}
export const adapter: EntityAdapter<prsnlStateInterface > = createEntityAdapter<prsnlStateInterface >();
export const initialState: State = adapter.getInitialState({
// additional entity state properties
selectedUserId: null,
});
const persnlReducer = createReducer(
initialState,
on(PrsnlActions.addPrsnl, (state, { prsnl }) => {
return adapter.addOne(prsnl, state)
})
);
export function prsnlReducer(state: State | undefined, action: Action) {
return persnlReducer(state, action);
}
Now I want to combine the 3 reducers into a single mainReducer in order to register it with the StoreModule.forFeature() inside my auth module. Because the ngrx combineReducer documentation is too succint to help, all I could do in the mainReducer.ts is as bellow:
mainReducer.ts
import * as fromLogin from 'src/app/auth/store/reducers/loginReducers';
import * as fromPrsnl from 'src/app/auth/store/reducers/prsnlReducer';
import * as fromUser from 'src/app/auth/store/reducers/userReducer';
export interface AuthModuleState {
login: AuthStateInterface
prsnl: prsnlStateInterface
user: userStateInterface
}
export interface State {
authModule: AuthModuleState;
}
export const mainReducer = {
login: fromLogin,
prsnl: fromPrsnl,
user: fromUser
};
export const selectAuthModuleState = createFeatureSelector<AuthModuleState>('authModule');
export const selectLoginState = createSelector(
selectAuthModuleState, (state: AuthModuleState) => state.login
);
Then I register the mainReducer.ts in the authModule with
StoreModule.forFeature('auth', mainReducer),
But visual studio errors out "that No overload matches this call" as you can see on screenshot:
How can I then combine the 3 reducers properly and register them in module for use ? Or is there any better way to handle such goal ? I will really appreciate your help to solve this empedement. Thanks in advance.
If you want to centralize your reducers into one source of truth then use combineReducers()
available in angular. You can adapt it to your case like this
export interface AuthModuleState {
login: any
prsnl: any
user: any
}
export const mainReducer:AuthModuleState = {
login: fromLogin.loginReducer,
prsnl: fromPrsnl.prsnlReducer,
user: fromUser.userReducer
};
const combineReducer = combineReducers(mainReducer)
export function reducer(state:any, action:any){
return combineReducer(state, action);
}
Then you just use the exported reducer
in module as you already did with forFeature.
StoreModule.forFeature('auth', reducer),