78

I have a structure like the following:

skillet.person = {
  name: {
    first: '',
    last: ''
  }, 
  age: {
    current: '' 
  },
  birthday: {
    day: '',
    month: '',
    year: ''
  }
}

I was wondering how I would update these values ? i.e. I thought the following was correct

skillet.person.name.push({ first: 'blah', last: 'ha'});

but it's wrong? How can I fix this?

1

10 Answers 10

123

Using ES7+ syntax and a functional approach:

const new_obj = { ...obj, name: { first: 'blah', last: 'ha'} }
Sign up to request clarification or add additional context in comments.

5 Comments

what about const new_obj = { ...obj, name: { first: 'blah'} }? I missed the last property!
I that way, you're removing the last property. If you want to update just the first property (without deleting the last property), you should do const new_obj = { ...obj, name: { ...obj.name, first: 'blah'} }.
This spread operator with an object works in React for setting State as well.
is ...obj supposed to be replaced with skillet.person in this example? Or ...skillet.person?
@jschmitter ...obj is equivalent to ...skillet.person here
41

On recent browsers with ECMAScript 2015, you can do:

Object.assign(skillet.person.name, { first: 'blah', last: 'ha'});

which will preserve any existing attribute not listed in the right object.

Reference: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign

[EDIT] With ES7, you can do even shorter, but it recreates the object (unlike Object.assign) and then adds some overhead if you care about performance. (comment thanks to Jamie Marshall)

{...skillet.person.name, ...{ first: 'blah', last: 'ha'}};

Reference: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax

2 Comments

There is a small difference in the second choice, the property(ie. functions) will not be preserved in the second choice.
Are you not recreating the object from scratch with the second choice? I believe that would be greater overhead.
37

As @ramon-diogo wrote with ES7+

I like to update nested values like:

let user = {
    name: {
        first: 'john',
        last: 'smith'
    },
    age: 18,
    city: 'new york'
}

const age = 20;

user = {...user, age}

console.log(user.age)
// output: 20


const newData ={
    age: 22,
    city: 'san francisco'
};

user = {...user,...newData}

console.log(user.name.first)
// output: john
console.log(user.age)
// output: 22
console.log(user.city)
// output: 'san francisco'

1 Comment

this is the only generic answer that can be applied for any use case
30
skillet.person.name.first = "blah"
skillet.person.name.last = "ha"

or

skillet.person.name = {first : "blah", last : "ha"}

6 Comments

thanks for the response. is there a faster way to update instead of listing each and every value if I dont want to replace the property if not all the values are available ?
@Andy: You may be looking for an extend function. See Underscore.js for an implementation.
@pimvdb - yeah at the moment I have a heap of properties but not all contain values. I was replacing the object with only partial properities and it was causing a prob - does this mean I must list each value like MrE has done or is there a faster way without replacing ?
@Andy: Do you have two objects of which the properties you want to blend together?
@pimvdb - i just have like an object with 9 properties but only usually update 6 of them. I tried { ... } but it will replace the 3 unfilled vals - so it means i must write 6 properties like skillet.person.name.first etc ?
|
25

If you want to mix an object into another one, you can use jQuery's deep extend function. "Deep" means that it does not overwrite name with the new object, but rather overwrites the properties inside such an object.

$.extend(true, skillet.person, {
  name: {
    first: 'updated'
  },
  birthday: {
    day: 'updated',
    year: 'updated'
  }
});

Now, skillet.person has the appropriate properties updated, while the other properties are untouched.

Comments

5

push is a method of Arrays that adds a new item to an array.

If you want to replace the value then:

skillet.person.name = { … };

If you want to store multiple (full) names in the object, then you'll need the property to hold an array of objects instead of a single object.

2 Comments

thanks is there a faster way to update instead of listing each and every value if I dont want to replace ?
@Andy: You can iterate over object properties. for(var prop in newValues) { oldValues[prop] = newValues[prop];} (in a gist). MDN also has a good page about for...in. Have a look at it.
4

I think that is simpler

     let skillet = {
        person: {
            name    : {
                first: '',
                last : ''
            },
            age     : {
                current: ''
            },
            birthday: {
                day  : '',
                month: '',
                year : ''
            }
        }
    };

    let update = {
        person: {
            name: {
                first: 'blah',
                last : 'ha'
            }
        }
    };

    let result = Object.assign(skillet.person, update.person);

    console.log(result);

2 Comments

What if I just have to update 'last' without affecting 'first'?
Following the same example as platie, I think the easiest way to edit only one element is this way: . . skillet.person.birthday.year = 2019 console.log({...skillet.person, ...skillet.person.birthday.year});
1
skillet.person.name.first = "blah"
skillet.person.name.last = "ha"

The easiest way.

Comments

0

Easist and simple way to update the javascipt object properties

  const skillet = [
 person = {
  name: {
    first: 'Arbaz',
    last: 'khan'
  }, 
  age: {
    current: 'ten' 
  },
  birthday: {
    day: '',
    month: '',
    year: ''
  }
}
]

suppose we want to update the first name. This is how we will do this in ES7+

skilled.map(person => {...person,person.name.first:"Arbaz2"})

The above code will update all the objects. On the other hand if you want to update only particular object. We can do this as well we just need one condition here. But in that case you need unique field as well let call it personId.

   skillled.map(person => person.personId === personId ? {...person,person.name.first:"Arbaz2"} : person);

1 Comment

The .map syntax is invalid, as is the spread syntax. You should at least check for code validity before posting answers.
-1
skillset.person.name = {};

This is the easiest way to assign value to the property of an object.

1 Comment

It looks almost like Quentin's answer in 2012. Are there any improvements or changes?

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.