95

I have a function that adds a key to incoming object, but I have been told to use the spread operator for that, I have been told that I can use the spread operator to create a new object with the same properties and then set isAvailable on it.

  return new Partner(ServerConfig, capabilities, initialState)
}

class Partner {
  constructor (ServerConfig, capabilities, initialState) {
    initialState.isAvailable = true

So I tried something like this but couldn't succeed, can you help me? and confused, should I use the spread operator in this way, return from a function ?

newObject = {}

// use this inside a function and get value from return

       return {
         value: {
           ...newObject,
           ...initialState
         }
       }

initialState.isAvailable = true
Yilmaz
  • 35,338
  • 10
  • 157
  • 202
Rasim Avcı
  • 1,123
  • 2
  • 10
  • 16

3 Answers3

185

The properties are added in order, so if you want to override existing properties, you need to put them at the end instead of at the beginning:

return {
  value: {
    ...initialState,
    ...newObject
  }
}

You don't need newObject (unless you already have it lying around), though:

return {
  value: {
    ...initialState,
    isAvailable: newValue
  }
}

Example:

const o1 = {a: "original a", b: "original b"};
// Doesn't work:
const o2 = {a: "updated a", ...o1};
console.log(o2);
// Works:
const o3 = {...o1, a: "updated a"};
console.log(o3);
T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
47

If you know the name of the property (a in the example below), then @crowder's answer is perfect:

const o3 = {...o1, a: "updated a"};
console.log(o3);

If the property name is in a variable, then you need to use Computed Property names syntax:

let variable = 'foo'
const o4 = {...o1, [variable]: "updated foo"};
console.log(o4);
Brent Washburne
  • 12,904
  • 4
  • 60
  • 82
0

Spreading the object usint ... will keep your state integrity. Let's say you have an initial state

 initialState={isOpen:false,count:0}

Assume that you want to add another property but you want to keep other properties:

return {  ...initialState,isAvailable:true
        }

this will lead to

 initialState={isOpen:false,count:0,isAvailable:true}

we just added a new property without discarding the other properties. maybe another part of your app is using other properties so we still keep them. let's say you want to update isOpen state. you spread the initial state first and then add the last piece of logic

 return {  ...initialState,isOpen:true
        }

this will lead to this

initialState={isOpen:true,count:0,isAvailable:true}

Now maybe on your current page, since isOpen:true you might be showing a different piece of UI to the user. Let's say you want to update the count this time. You could write this too

 return {  count:5 }

Now your current state has only count:5 so you have lost other properties in your state. Now there is no isOpen property. If you did not handle the isOpen logic successfully while you were displaying a different UI, your app will crash. but if you handle correctly, isOpen would lead to falsy so your page will not show that piece of UI to the user.

Yilmaz
  • 35,338
  • 10
  • 157
  • 202