I have the @ngrx/store
package in my angular (4.x) app, and am upgrading from v2.2.2 -> v4.0.0. I can see that the migration notes say:
The payload property has been removed from the Action interface.
However, the example they give seems completely counter intuitive (in my view...).
I have a reducer function which looks like this:
export function titleReducer(state = { company: 'MyCo', site: 'London' }, action: Action): ITitle {
switch (action.type) {
case 'SET_TITLE':
return {
company: action.payload.company,
site: action.payload.site,
department: action.payload.department,
line: action.payload.line
}
case 'RESET':
return {
company: 'MyCo',
site: 'London'
}
default:
return state
}
}
Which as expected now throws typescript error:
[ts] Property 'payload' does not exist on type 'Action'
But I have no idea from the migration guide what this should be changed too. Any ideas?
You can create your own action type that has a payload
defined, check the example app for reference:
class AddBookAction implements Action {
readonly type = ADD_BOOK;
constructor(public payload: Book) {}
}
Then use that type in the reducer:
function reducer(state = initialState, action: AddBookAction): State
Action could be dispatched like this:
this.store.dispatch(new AddBookAction(book));
Note also that the example app combines all the action types that a reducer can take into a single union type:
export type Actions =
| AddBookAction
| AddBookSuccessAction
export function reducer(state = initialState, action: Actions): State
Ok, it's very interesting topic. I missed new realese (4.0) but I updated libraries in my repo and I saw that I have the same problem.
That's right. Payload attribute was deleted from Action in new release. If are you use effects to dispatch action, solution is simple and can you read them in migration note
but if you want dispatch to pass payload, you can create parametrizied Action in this way:
export interface ActionWithPayload<T> extends Action {
payload: T;
}
so if you added this interface you can change reducer in this way:
export class SomeObject {
company: string;
site: string;
department: string;
line: string;
}
export function titleReducer(state = { company: 'MyCo', site: 'London' }, action: ActionWithPayload<SomeObject>): ITitle {
switch (action.type) {
case 'SET_TITLE':
return {
company: action.payload.company,
site: action.payload.site,
department: action.payload.department,
line: action.payload.line
}
...
It's the best walkaround, what I found. I must understand better the reason for this change, and if I will find better soulution I added them here
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With