2

First note that this is a question from my Redux code HERE.

Okay so lets say I want to edit the property of 'status' from "pending" to "deleted" to a specific property of an object within an array, how would I be able to do this using Object.Assign for the following examples:

Example a: (notice the the array of objects is stored within an object itself)

const plan = {
  task: [
    {
        id: 1,
        description: "This is a task",
        status: "pending"
    },
    {
        id: 2,
        description: "This is a second task",
        status: "pending"
    }
  ]
}

Example b: (A simple array of elements whose elements are objects)

const task2 = [
    {
        id: 1,
        description: "This is a task",
        status: "pending"
    },
    {
        id: 2,
        description: "This is a second task",
        status: "pending"
    }
]

1
  • good point, thanks! fixed it Commented Nov 4, 2016 at 9:34

2 Answers 2

2

Great question. The morphisms you're aiming to do are often referred as Lenses (which are a bigger grouping of morphisms, actually).

You can achieve it with pure JavaScript, for example:

// Return a new object with the very same structure as plan and an amended list of tasks
return Object.assign({}, plan, {
  tasks: plan.tasks.map(function (task) {
    // Map every existing task to a totally new object with the very same structure and a new status
    return Object.assign({}, task, { status: "deleted" })
  })
})

The second example is even easier to morph, check the following code:

return task2.map(function (task) {
  // Return a totally new object with the very same structure as task and a new status
  return Object.assign({}, task, { status: "deleted" });
})

What's more, there are also some libraries available out there that do exactly what you want, e.g. nanoscope

Sign up to request clarification or add additional context in comments.

Comments

2

NOTE I'm using the code from your first question

Ok so firstly in your renderList function you'll need to include an onclick handler to register when a task is done:

renderList() {
  return this.props.tasks.tasks.map((task) => {
    if(task.status == "pending"){
        return (
          <li key={task.id}>
            {task.id} {task.description}
            <button type="button">Finish</button>
            <button type="button">Edit</button>
            <button onClick={() => this.props.deleteTask(task.id)} type="button">Delete</button>
            </li>
          );
      }
  else return(
    <div key={task.id}>
      THIS TASK HAS BEEN DONE
    </div>
  );

}); }

Next, in your ActionIndex.js you should be recording WHICH action was selected, not just the message "deleted". SO change it to this:

export const deleteTaskAction = (taskId) => {
        return {
            type: 'DELETE_TASK',
            payload: taskId //pass on task id
        }
    };

Finally, in your reducer-tasks.js you should update the 'status' property of that specific list item when that action is dispatched (via the button click):

case 'DELETE_TASK':
    let newTasks = state.tasks.map( (task) => {
        if(task.id !== action.payload) {
            return task;
        }

        return Object.assign({}, task, {status : "deleted"});
    });

    const newState = Object.assign({}, state, {tasks : newTasks});
    return newState;

This should update the state and change the status of the selected task from "pending" to "deleted", which should trigger a re-render and change that element.

Let me know if you have any questions/issues

6 Comments

Ah that clears a lot up. However I get newState.tasks[action.payload] is undefined. I printed newState and it does copy the array of objects correctly. Not sure whats going there
If you print action.payload is that defined?
Yes its defined properly, it points to the correct object showing the id, description and status accordingly
action.payload should just equal the id, not the whole object
WARNING: the reducer example given is directly mutating the tasks object! You need to make a copy for every level of nesting involved in that data. Please see the Immutable Update Patterns page in the "Structuring Reducers" section of the Redux docs for examples of how to properly do nested updates, including this specific scenario.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.