简体   繁体   中英

Trouble with updating ngrx state

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?

PS

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?

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 .

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, }, }; } ),

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM