I'm refactoring my NgRx reducer to use the createReducer()
function instead of the traditional switch statement, but I'm getting the following errors:
ERROR in src/app/store/price.reducer.ts(17,32): error TS2339: Property 'action' does not exist on type 'IUser & TypedAction<"[Websocket Service] Get User"> & { type: "[Websocket Service] Get User"; }'.
src/app/store/price.reducer.ts(18,34): error TS2339: Property 'action' does not exist on type 'IPrice & TypedAction<"[Websocket Service] New Prices"> & { type: "[Websocket Service] New Prices"; }'.
This is my createReducer()
function and the exported reducer itself:
const userPriceReducer = createReducer(
defaultState,
on(actions.getUser, (state, {action}) => ({ ...state, user: { firstName: <string>action.firstName, lastName: <string>action.lastName, age: <number>action.age } })),
on(actions.newPrices, (state, {action}) => ({ ...state, prices: { ...state.prices, ...{[action.product_id]: <number>action.price } } }))
)
export function reducer(state: State | undefined, action: Action) {
return userPriceReducer(state, action);
}
And here are my actions:
export const NEW_PRICES = '[Websocket Service] New Prices';
export const GET_USER = '[Websocket Service] Get User';
export const newPrices = createAction(
NEW_PRICES,
props<IPrice>()
);
export const getUser = createAction(
GET_USER,
props<IUser>()
);
IPrice
and IUser
are interfaces that describe the shape of the action data.
The documentation that I've read about this says that the second argument inside the curly braces after state
in the createReducer()
function (where I've put {action}
) is supposed to be the payload of the action, however since I'm using createAction()
for my actions, there is no actual payload
property in the action as there used to be and the action itself carries the data. I have no problem accessing and saving this data when using the switch statement approach. What am I doing wrong here?
Your action doesn't have an action property, it should be
const userPriceReducer = createReducer(
defaultState,
on(actions.getUser, (state, action) => ({ ...state, user: { firstName: <string>action.firstName, lastName: <string>action.lastName, age: <number>action.age } })),
on(actions.newPrices, (state, action) => ({ ...state, prices: { ...state.prices, ...{[action.product_id]: <number>action.price } } }))
)
or:
const userPriceReducer = createReducer(
defaultState,
on(actions.getUser, (state, {firstName,lastName,age}) => ({ ...state, user: { firstName: <string>firstName, lastName: <string>lastName, age: <number>age } })),
on(actions.newPrices, (state, {price}) => ({ ...state, prices: { ...state.prices, ...{[action.product_id]: <number>price } } }))
)