Your Web News in One Place

Help Webnuz

Referal links:

Sign up for GreenGeeks web hosting
August 20, 2021 04:59 am GMT

Remove a property of an object immutably in REDUX JavaScript

If you're using Redux then you'll absolutely know about immutability, how much it's important to follow.

So we know that Reducer is the place where all good state change occurs with returning a new state and without modifying the previous state.

Imagine you're building a Bug Tracker App, and It stores all details about bug which are occurred.

Suppose your initial store looks something like this

[ {   id:"1",   description:"Bug occured in Network call",   resolved:false, }, {   id:"2",   description:"Bug occured while Signup",   resolved:false, }]

Also We are logging on console every time store change using store.subscribe():

store.subscribe(() => {  console.log("store changed!", store.getState());});

Now Suppose you are dispatching action when some developers in working on the bug to resolve it but it's not resolved yet.

Below is code of action which will take place

export const bugResolving = (id, status) => ({  type: actions.BUG_RESOLVING,  payload: {    id: id,    status: status,  },});

And from your code you're calling store.dispatch() something like this:

store.dispatch(bugAdded("Bug occured in Network call"));store.dispatch(bugAdded("Bug occured while Signup"));store.dispatch(bugResolving(1, "resolving in process by devDiesel"));

And from your code you're calling store.dispatch() something like this:

store.dispatch(bugResolving(1, "resolving in process by devDiesel"));

Thus your store will look something like this:
image

As you can see in last store change we added status property in bug with id=1.

Now After a cup of coffee the Dev was able to solve and bug was marked as solved.
Hooray!!

As you've guessed now we want to remove the status property from store object whose id is 1, and also update the resolved to true

So in your reducer function you might write code like this:

function reducer(state = [], action) {  switch (action.type) {   case actions.BUG_ADDED:    //Some Code   case actions.BUG_REMOVED:    //Some Code   case actions.BUG_RESOLVING:    //Some Code   case actions.BUG_RESOLVED:    return state.map((bug)=> {      if (bug.id === action.payload.id){        delete bug.status;        return { ... bug, resolved:true};      }      else return bug;    default:      return store;    }}

So we will dispatch the action like this:

store.dispatch(bugAdded("Bug occured in Network call"));store.dispatch(bugAdded("Bug occured while Signup"));store.dispatch(bugResolving(1, "resolving in process by devDiesel"));store.dispatch(bugResolved(1)); //This one

So when the reducer runs BUG_RESOLVED it won't work as expected and will delete the status property from previous original bug state,instead of deleting where we wanted.

And thus will only update resolved to true in last state.

Which can be seen with the help of console logging of subscribe() method as described in starting.

See In this picture:
image

So Why this happened??

As JavaScript is not purely immutable language when we return new state object using return state.map((bug)=>{...}) it does shallow copy of objects.

That is the status property which we are created in previous state and status property which is we deleting are pointing to the same memory address.

Thus when we delete this property it's get deleted from both object as its referring to same location inside memory

Then How to force immutability Now??

We can do deep-copy of the object using Object.assign() method.

 case actions.BUG_RESOLVED:      return state.map((bug) => {        let modifiedBug = Object.assign({}, bug);//1        if (modifiedBug.id === action.payload.id) {          modifiedBug.status = Object.assign({}, bug.status);//2          delete modifiedBug.status;//3          return { ...modifiedBug, resolved: true };//4        } else return bug;      });

In above code:

1.) We assigning new object using Object.assign() thus modifiedBug will get its own address in memory.

2.) We setting modifiedBug.status property with new bug.status using Object.assign() this will also force to have it's separate memory address

3.)Now we are deleting the modifiedBug.status which won't affect any previous bug object cause its pointing to totally different location.

4.) In last we are appending resolved:true to modifiedBug Object and returning it.

Thus now our code will work as we expected

image

Thank You For Reading Out.

Post any questions in comments if you have


Original Link: https://dev.to/karanmunjani/remove-a-property-of-an-object-immutably-in-redux-javascript-4igj

Share this article:    Share on Facebook
View Full Article

Dev To

An online community for sharing and discovering great ideas, having debates, and making friends

More About this Source Visit Dev To