Copy an Object with Object.assign- Redux

Copy an Object with Object.assign- Redux
0

#1

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.


const defaultState = {
  user: 'CamperBot',
  status: 'offline',
  friends: '732,982',
  community: 'freeCodeCamp'
};

const immutableReducer = (state = defaultState, action) => {
  switch(action.type) {
    case 'ONLINE':
      let newObj = state;
      return Object.assign(newObj, {status: action.type});
    default:
      return state;
  }
};

const wakeUp = () => {
  return {
    type: 'ONLINE'
  }
};

const store = Redux.createStore(immutableReducer);

Your browser information:

User Agent is: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.87 Safari/537.36.

Link to the challenge:
https://learn.freecodecamp.org/front-end-libraries/redux/copy-an-object-with-object-assign


#2

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.


#3

I did it as well but it isn’t working

const defaultState = {
  user: 'CamperBot',
  status: 'offline',
  friends: '732,982',
  community: 'freeCodeCamp'
};

const immutableReducer = (state = defaultState, action) => {
  switch(action.type) {
    case 'ONLINE':
      let newObj = Object.assign({}, {status: action.type});
      return newObj;
    default:
      return state;
  }
};

const wakeUp = () => {
  return {
    type: 'ONLINE'
  }
};

const store = Redux.createStore(immutableReducer);

#4

So, going from what I said, remenber that you merge right-to-left and you can pass as many objects as you like to assign.

What you’re meant to do is merge {status: 'online'} into your state. Then that merged object gets merged into the new, empty object {}.

At the minute, you’re just merging the {status: 'online'} into a new object, so that’s all you end up with.


#5

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.

Happy Coding!!


#6

Just like you said, it does the work

const newObj = Object.assign({}, state ,  {status: 'online'})
return newObj;

#7

True.
It’s even cleaner if we just go:

return Object.assign({}, state, {status: 'online'});

#8

Since we have been given an action, we ought to use that instead of hard coding “online”. I guess the most accurate solution would be:

return Object.assign({}, state, {status: action.type.toLowerCase()});