Your Web News in One Place

Help Webnuz

Referal links:

Sign up for GreenGeeks web hosting
June 22, 2020 11:10 pm GMT

How to Merge Objects with the Object Spread Operator

Say we have an application where we want to create a user when they sign up.

A user will look something like this, and consists of a number of properties, their name, their username, their phone number, their email and their password:

const user = {  name: "",  username: "",  phoneNumber: "",  email: "",  password: "",};

And lets say that when a user signs up, they dont need to provide all this data at once. This is standard for most applicationsto make it easy for people to get through they just have to fill out a few necessary fields such as their username, email and password. Well let users fill out these non-required fields like their phone number and name after they have created an account.

A user fills out the form and gives us these required values. We store them on an object called newUser:

const newUser = {  username: "ReedBarger",  email: "[email protected]",  password: "mypassword",};

How do we use all of this data on the newUser object, but still use user as our model?

Meaning, we want to merge these two objects, so we get all five properties that are needed for each user, including the empty values for name and phoneNumber.

To create a new object that preserves our default properties on the user object, while merging with new data, is possible with a new object method called Object.assign.

Object.assign() lets you update an object with properties from another object.

How Object.assign works

The first object that we pass to Object.assign is the object that we want to be returned.

For any other arguments, those are objects that we want to merge into the first object. That is, we want to take their properties and put them on the first object. If properties of other objects have the same name as the first one, as is the case with username, email and password, their values will be added to the original object.

So based off of what we now know about Object.assign, what do you think the result will be?

Object.assign(user, newUser); // {name: "", username: "ReedBarger", phoneNumber: "", email: "[email protected]", password: "mypassword"}

We get an object with the same keys as our original user object, but whose values are updated. Specifically the values for username, email and password.

Why? Because newUser had those same properties as user, and since they were merged into user, the original values were overwritten.

Easy to mutate data with Object.assign

However, theres a problem with Object.assign() as were currently using it. We can see it if remove the console.log, but still execute Object.assign and then log the original user object afterwards.

// Object.assign(user, newUser);user; // {name: "", username: "ReedBarger", phoneNumber: "", email: "[email protected]", password: "mypassword"}

Whats happening is that Object.assign is mutating our original user object.

Objects are by passed by reference and not by value. As a result, we can get unexpected errors like this one.

To fix this, we dont want to merge new values onto the original user object, but instead, use an entire new object. We can create as the first argument to Object.assign a brand new object to be updated and then returned, and then merge in the data from user and, after that newUser:

Object.assign({}, user, newUser); // {name: "", username: "ReedBarger", phoneNumber: "", email: "[email protected]", password: "mypassword"}

The returned object has the correct values as before, but if we now take another look at the original user object it retains its original values:

user; // {name: "", username: "", phoneNumber: "", email: "", password: ""}

Be aware that to avoid updating or mutating, as its called, our original data, pass an empty object as the object to be returned from Object.assign.

Merging many objects with Object.assign()

This is a common problem that Object.assign helps us out with a lot when you have an object with values, but is missing some key-value pairs. As a result, we need to fill in the remaining fields using a default object, in this case user.

Object.assign can merge as many objects as we want into the first object. For example, say we want to add a verified property to each user that by default is false, to indicate that their email that they provided for signup is not verified yet:

How would we do that? Take a minute and try to merge such a property on the user object on your own

We could create a new object, say one called defaultStatus, or something like that, where the property verified is false:

const defaultStatus = {  verified: false,};

And if we add it as a fourth argument

Object.assign({}, user, newUser, defaultStatus); // { email: "[email protected]", name: "", password: "mypassword", phoneNumber: "", username: "ReedBarger", verified: false }

This will work.

However, in this case, what might be a bit cleaner is to add the object inline without declaring it as a variable. Be aware that you can do so for small objects such as this one:

// const defaultStatus = {// verified: false// }Object.assign({}, user, newUser, { verified: false }); // { email: "[email protected]", name: "", password: "mypassword", phoneNumber: "", username: "ReedBarger", verified: false }

And this works exactly the same.

To review, all that Object.assign is responsible for doing is gather object properties and putting it into a new object.

But as you can see, working with Object.assign is not very intuitive. Its weird to have to pass in that first empty object to avoid inadvertent mutations. And also, from a readability standpoint, its not clear when we look at this line whats happening is that were creating an object from other objects and properties. We dont exactly know what the .assign method does from first glance.

Introducing the Object spread operator

Instead of using Object.assign, couldnt we just tell JavaScript that we want to take all the properties from an object and put in it a new one.

So lets start by creating a new variable called createdUser to store our final user data. And well just set this equal to an object:

const createdUser = {};

Now we want to tell JS that we want to just get all of the properties from the user object and then spread them into this new object.

const createdUser = { user };

And then after the user data, to put in the newUser data:

const createdUser = { user, newUser };

And the finally, instead of providing an object, we just put in the property that we need at the end: verified set to false:

const createdUser = { user, newUser, verified: false };

But with this syntax, we know that were going to be creating nested objects on the properties user and newUser. How can we just tell JS to spread all of the properties from an object into a new one?

In ES2018, such a feature arrived to do just that, called the object spread operator.

To spread in an objects properties into another one, we just have to include this syntax ... before the object. Well do that to both user and newUser. And if we log this:

const createdUser = { ...user, ...newUser, verified: false };createdUser; // { email: "[email protected]", name: "", password: "mypassword", phoneNumber: "", username: "ReedBarger", verified: false }

We see that we get the same exact result as with Object.assign. Since thats the case, we know that the spread operator works in effectively the same wayit merges the properties that come later (after each comma) with the properties provided at the beginning. It does so as well in an immutable way.

With the object spread operator, we have all the advantages of Object.assign() with reduced syntax and to create objects in a more intuitive way.

Order matters with Object.assign() and spread operator

One final note is that the order matters significant for both Object.assign and the spread operator. If you add a value with the same key, it will use whatever value is declared last.

Say for example, we update our original user object to include the verified property. But here verified is set to true by default. If we console log our createdUser again, what will the final value of verified be on it?

const user = {  name: "",  username: "",  phoneNumber: "",  email: "",  password: "",  verified: true,};const createdUser = { ...user, ...newUser, verified: false };createdUser; // { email: "[email protected]", name: "", password: "mypassword", phoneNumber: "", username: "ReedBarger", verified: false }

We see that verified is false. Thats because the last value a property is supplied is what the created object is provided with. So since verified was set to false at the end, thats why it ultimately had the value false.

As a rule, when performing updates to existing properties, make sure to provide update values at the end, or at least after the existing ones.

Summary

In this article, weve covered both Object.assign and the object spread operator. They both do the same thing, but in general the object spread is much more straightforward to use since its more evident that we are just creating a basic object.

You tend to see it much more often that Object.assign and I would recommend you use the object spread the majority of time in your code. Theres no significant advantage that Object.assign has over it.

And also, we covered both important use-cases for Object.assign and the object spread:

  1. Using them to establish common defaults properties of any object through merging two or more objects. And
  2. To be able to non-destructively update or add properties. So we saw how to update the final object with the verified property in a way that didnt mutate our original user objects.

Want To Become a JS Master? Join the 2020 JS Bootcamp

Join the JS Bootcamp Course

Follow + Say Hi! Twitter Instagram reedbarger.com codeartistry.io


Original Link: https://dev.to/codeartistryio/how-to-merge-objects-with-the-object-spread-operator-1il8

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