Hey there can you help me with the code. Whenever I’m running the tests its showing that “Cannot assign to read only property ‘status’ of object ‘#’”
I can’t figure out what’s wrong.
let newObj = state; - this isn’t a new object, it’s just a reference to the original object. This isn’t specific to what your doing, it’s how JS works.
With Object.assign though, you can assign to a new object, so if you have Object.assign({}, {foo: 1, bar: 2}, {foo: 2}) (note the empty object there) it will merge the object on the right with the the next one, so {foo: 2} over {foo: 1, bar: 2}. That means there’s a new value for foo, so you get {foo: 2, bar: 2}. Then it takes that and merges it with the next one, which is an empty object (so you still end up with {foo: 2, bar: 2} in this example, but if either of the second or third objects had been references, the end result would have been a new object unconnected to them)
tl/dr if you want to create a new object with Object.assign, put an empty object in as the first argument, and it will merge any other objects you give into that new object. It’s what’s called a shallow copy.
Object.assign will copy all the properties from source to target. Basically, after allocating all the properties to the new object, you need to change the status property of the new object to online.
You need to do something like this:
let newObj = Object.assign({},state);
newObj.status=‘online’;
return newObj;
It will not mutate the original state and changes the “status” property of the new object to online.
As others have pointed it out, let newObj = state; won’t copy state to newObj. This is reference assign, not value. So whatever you do to newObj will have impact on state.
My first solution was copy state to some new object, then modify the status property of that new object. Finally, return the new object. But that’s a 3 lines of code:
There’s another way to do this with just one concise line. As the assign() method can take more than 2 arguments, here’s how you can do this with explanation:
The first argument, {}, is the initial look of the new object. state is the whole object we want to copy. So if we stop at this point, our new object is an exact copy of the state with just same properties and values.
However, you can provide a third argument as a object with property status as the only one property. This property will override the status property of the new object, making its value to be ‘online’.
I believe we should know and understand all the techniques manipulating object and array if we want to advance further.
return Object.assign({}, state, {status: ‘online’}); is the key here. https://redux.js.org/recipes/usingobjectspreadoperator has a great article with in depth explanations and examples, I encourage everyone with Redux problems to visit this page as it has helped me many times over.
FYI, I was receiving an error when I coded this because I had capped ‘online’ lol. When I read this post, I was reminded to use lower caps. I hope this helps someone out there, happy coding all!
Yeah, I don’t know what I was thinking. It merges right to left, I knew that, but for some reason I wasn’t thinking clearly enough about it. If state is passed last, status gets overwritten by state’s status.