Reputation: 1565
I'm using the NgRx
library in my new Angular 8 project. I've been told that they create the actions using createAction
i.e. NgRx 8
but they create the reducers using NgRx 7
. I was given a task in which I used NgRx 8
for my reducer which I now have to change to NgRx 7
. My actions and reducer are as below:
book.actions.ts
import { createAction, props } from "@ngrx/store";
import { Book } from "./book";
export const BeginGetBooksAction = createAction("BeginGetBooks");
export const SuccessGetBooksAction = createAction(
"SuccessGetBooks",
props<{ payload: Book[] }>()
);
export const BeginAddBookAction = createAction(
"BeginAddBook",
props<{ payload: Book }>()
);
export const SuccessAddBookAction = createAction(
"SuccessAddBook",
props<{ payload: Book[] }>()
);
book.reducer.ts
import { Action, createReducer, on } from "@ngrx/store";
import * as BooksActions from "./book.action";
import { Book } from "./book";
export interface BooksState {
Books: Book[];
ReadBooks: { book: Book; addedOn: Date }[];
WantToReadBooks: { book: Book; addedOn: Date }[];
editBook: Book;
}
const initialState: BooksState = {
Books: [],
ReadBooks: [],
WantToReadBooks: [],
editBook: new Book()
};
export function booksReducer(state = initialState, action: Action) {
switch (action.type) {
case BooksActions.BeginGetBooksAction.type:
return state;
case BooksActions.SuccessGetBooksAction.type:
return { ...state, Books: action.payload };
case BooksActions.BeginAddBookAction.type:
return state;
case BooksActions.SuccessAddBookAction.type:
return { ...state, Books: action.payload };
default:
return state;
}
}
I get an error for action.payload
Property 'payload' does not exist on type 'Action'.
Can someone tell me what I am doing wrong???
Upvotes: 2
Views: 970
Reputation: 15487
I wrote down a comparison in NgRx creator functions 101.
In the article you can see how you can combine the syntax of both versions:
export const addToCart = createAction(
// action's type
'[Product List] Add to cart',
// optional payload
props<{ sku: string }>(),
)
export const removeFromCart = createAction(
'[Product List] Remove from cart',
props<{ sku: string }>(),
)
export function reducer(
state = initialState,
action: ReturnType<typeof addToCart> | ReturnType<typeof removeFromCart>,
) {
switch (action.type) {
case addToCart.type:
return {
...state,
cartItems: {
...state.cartItems,
[action.sku]: (state.cartItems[action.sku] || 0) + 1,
},
}
case removeFromCart.type:
return {
...state,
cartItems: {
...state.cartItems,
[action.sku]: Math.max((state.cartItems[action.sku] || 0) - 1, 0),
},
}
default:
return state
}
}
Upvotes: 5
Reputation: 1640
Your reducer is good, just your type definition is the problem. You use a plain Action
type where payload doesn't exists. Try another type definition, like any
or try union types, but when you try union types, you need all named imports from the action file.
I think the best solution for you is the next generation syntax of reducer, try use the new format.
Upvotes: 0