I am trying to create a simple application to better understand how NgRx works. For that i have developed the following code. But it is not working as expected.
My Action.ts:
import { Action } from '@ngrx/store';
import { Employee } from '../Employee.model';
export const ADD_EMPLOYEE = 'ADD_EMPLOYEE';
export const EDIT_EMPLOYEE = 'EDIT_EMPLOYEE';
export class AddEmployee implements Action {
readonly type = ADD_EMPLOYEE;
constructor(public payload: Employee){}
}
export class EditEmployee implements Action {
readonly type = EDIT_EMPLOYEE;
// constructor(public payload: Employee){}
}
export type EmployeeAction = EditEmployee | AddEmployee;
My reducer.ts
import * as EmployeeActions from './employee.actions';
const initialState = {
states: [
{name: 'Arizona', code: 'Arizona'},
{name: 'California', value: 'California'},
{name: 'Florida', code: 'Florida'},
{name: 'Ohio', code: 'Ohio'},
{name: 'Washington', code: 'Washington'}
],
};
export function employeeReducer (state = initialState, action: EmployeeActions.EmployeeAction) {
switch(action.type) {
case EmployeeActions.ADD_EMPLOYEE:
console.log("Employee reducer called: ", action.payload);
return {
...state,
};
default:
return state;
}
}
My app.module.ts:
import { StoreModule } from '@ngrx/store';
.....
imports: [
BrowserModule,
BrowserAnimationsModule,
StoreModule.forRoot({employeeStoreReducer: employeeReducer})
],
at this point i am getting the following error:
error TS2322: Type '(state: { states: ({ name: string; code: string; value?: undefined; } | { name: string; value: string; code?: undefined; })[]; } | undefined, action: EmployeeAction) => { states: ({ name: string; code: string; value?: undefined; } | { ...; })[]; }' is not assignable to type 'ActionReducer<{ states: ({ name: string; code: string; value?: undefined; } | { name: string; value: string; code?: undefined; })[]; }, Action>'.
Types of parameters 'action' and 'action' are incompatible.
Type 'Action' is not assignable to type 'EmployeeAction'.
Property 'payload' is missing in type 'Action' but required in type 'AddEmployee'.
36 StoreModule.forRoot({employeeStoreReducer: employeeReducer}),
src/app/employee/store/employee.actions.ts:10:17
10 constructor(public payload: Employee){}
'payload' is declared here.
But if i change action: EmployeeActions.EmployeeAction to action: Action it starts working. But in this case i cannot send any payload. Please help in resolving the issue and also let me know the reason for this. I can share more code if needed. I am using angular version 11.1.2, ngrx version 11.0.1. Thanks in advance.
If this project is using Angular/NGRX v11.x, and you are attempting to learn modern techniques with NGRX, I would discard the pattern you are using and use the factory functions provided by the library.
For example:
Action File
export const addEmployee = createAction(
ADD_EMPLOYEE,
props<{payload: Employee}>()
);
export const editEmployee = createAction(
EDIT_EMPLOYEE,
props<{payload: Employee}>()
);
Reducer File
export const reducer = createReducer(
initialState,
on(EmployeeActions.addEmployee, (state, { payload }) => {
console.log("Employee Reducer Called")
return {
...state, //Insert Add Logic here
};
}),
on(EmployeeActions.editEmployee, (state, { payload }) => {
console.log("Employee Reducer Called")
return {
...state, //Insert Edit Logic here
};
}),
);
The NGRX Docs show this effectively: https://ngrx.io/guide/store/reducers