Reputation: 757
I have an ngrx state like this:
company: {
id: '1',
name: 'myCompany',
task: [{id: 1, name: 'task1', date: '20-01-2021', endDate: '22-01-2021'}, {id: 2, name: 'task2', date: '23-01-2021', endDate: '24-01-2021'}]
}
I have a function reducer that needs to update only some property of the task array.
the action object contains a property task that's an object that contains only the property I need to edit, and the id to match into the array. This is the function buy I got error because the object is read only.
on(
CompanyAction.editTask,
(state, action): CompanyState => {
const index = state.company.tasks.findIndex(el => el.id === action.taskId);
// here I want to update the task that I've edited But I got error
state.company.tasks[index] = { ...state.company.tasks[index], ...action.task };
return {
...state,
company: {
...state.company,
tasks: state.company.tasks,
},
};
}),
Any suggestion?
P.S
I tried in this way, but if in the action I have only a single prop example name: string and I do this:
on(
CompanyAction.editTask,
(state, action): CompanyState => {
const newTasks = state.company.tasks.map(item => {
if (item.id === action.taskId) {
item.name = action.name // this gives me a read only error
} else {
return item;
}
})
return {
...state,
company: {
...state.company,
tasks: newTasks,
},
};
}),
It gives me the same read only error.
Isn't correct to pass in the ngrx action a prop with only a single value to update a single property of the object?
Upvotes: 0
Views: 130
Reputation: 56
Try this:
on(
CompanyAction.editTask,
(state, action): CompanyState => {
const index = state.company.tasks.findIndex(el => el.id === action.taskId);
let companyTasks = {...state.company.tasks};
let editingTask = companyTasks[index];
companyTasks = companyTasks.filter((task, idx) => {return idx !== index});
editingTask = {...editingTask, ...action.task};
companyTasks.push(editingTask);
return {
...state,
company: {
...state.company,
tasks: companyTasks,
},
};
}
First after finding index of desired task, Create a copy of all tasks named companyTasks
.
then pick the task based on index (editingTask
) and remove it from companyTasks
. after editing it push it to companyTasks
. and in returning state apply companyTasks
to tasks
.
Upvotes: 1
Reputation: 50291
Could not test it but you can try this.
on(
CompanyAction.editTask,
(state, action): CompanyState => {
const newTasks = state.company.tasks.map(item => {
if (item.id === action.taskId) {
// write code for what you wnat to do when id matches
} else {
return item;
}
})
return {
...state,
company: {
...state.company,
tasks: newTasks,
},
};
}
),
Upvotes: 0