Reputation: 1437
I read this tutorial on creating a NgRx store so I created a simple store with the following shape.
export const initialState: IState = {
app: initialAppState
};
export function getInitialState(): IState {
return initialState;
}
export interface IApp {
id?: string;
testMode?: boolean;
authenticated?: boolean;
user?: User;
role?: string;
}
export interface IAppState {
app: IApp;
}
export const initialAppState: IAppState = {
app: {
id: null,
testMode: false,
authenticated: false,
user: null,
role: 'END_USER'
}
};
It has one action PatchApp
with a reducer that looks like this
export const appReducers = (state = initialAppState, action: AppActions): IAppState => {
switch (action.type) {
case AppActionTypes.PatchApp: {
return { ...state, app: action.payload };
}
default:
return state;
}
};
Now to me, this seems super simple. We have an initial state that is stored in the app
property. If we get a payload to update the authenticated
property on the existing state, I would expect the reducer to overwrite just that property instead of the entire state.
But when I step through with the debugger, I can see the state get's updated with just the property that gets passed in.
So if I have the initial state like this:
export const initialAppState: IAppState = {
app: {
id: null,
testMode: false,
authenticated: false,
user: null,
role: 'END_USER'
}
};
then I do PatchApp
with {authenticated: true, id: 'someid'}
, I would expect the action.payload
to overwrite/merge/patch the existing object.
Instead what happens is the entire store get's overwritten with JUST the property. So after doing the afformentioned patch app, we would have just the authenticated
and id
props set.
Any idea why my reducer isn't behaving as expected? I read an article from Flavio Copes and don't see anything where I'm going wrong.
I also tried using Object.assign()
to merge the objects.
return Object.assign({}, state, { app: action.payload });
I have a CodeSandbox that illustrates the problem I'm trying to solve.
https://codesandbox.io/s/oxj7xx5n35?fontsize=14
Upvotes: 0
Views: 871
Reputation: 9377
Not sure whether I got right what you're trying to do, but it seems that you want to patch just the app
part of the state. If so, you should do it like this:
export const appReducers = (state = initialAppState, action: AppActions): IAppState => {
switch (action.type) {
case AppActionTypes.PatchApp: {
return {
...state,
app: {...state.app, ...action.payload}
};
}
default:
return state;
}
};
Upvotes: 3