Object destructuring in function parameters

We've seen the power of arrow functions to make our code far more concise, allowing us to remove a lot of boilerplate in creating functions. JS developers often reach for conventions like using arrow functions over regular functions for simple reasons, namely, less typing. Any developer who has written large applications with thousands of lines of code will tell you that it gets tiresome to have to write the function keyword over and over again.

In this video we're going to utilize arrow functions with a couple of other patterns to make our code even more succinct.

Let's say we have a simple function that is responsible for greeting our user in our application:

const user = { first: "Mark", last: "Zuckerberg" };

function greetUser(user) {
  return `Welcome back, ${user.first} ${user.last}`;
}

At the moment, our code is written with a function declaration and accepts the user's first and last name and returns to them a custom greeting.

But we can make this more succinct with the help of an arrow function, especially as simple a function as this. Take some time right now and convert this function into an arrow function...

We can remove the function keyword and assign the function to a variable with the name greetUser, add the fat arrow, and then remove the function body and explicit return and now the body is returned implicitly.

const greetUser = (user) => `Welcome back, ${user.first} ${user.last}`;

Note also that we can remove the parentheses around the parameters since we only have one parameter. We can only remove them if we have just one.

So we've cut down our code quite a bit, and turned three lines of code into just one. But we can improve it even more.

Let’s begin with destructuring. You remember from the object section that we can use the feature destructuring to more easily access properties from their objects. And what's neat is that with function parameters that are objects, we can perform destructuring right in the parentheses.

So now instead of having to repeat ourselves and say user.first and user.last, we can just destructure first and last and drop the user reference entirely:

const greetUser = ({ first, last }) => `Welcome back, ${first} ${last}`;

Now we're being even more concise. Note a couple things here, however. First, this object destructuring function parameters is not only possible with arrow functions. We can do them in function declarations as well. And also, we need to add back our set of parentheses around the parameters when we destructure objects in them. We can't just have an object as our parameters for a function. The following is invalid JS:

const greetUser = { first, last } => `Welcome back, ${first} ${last}`;

Now let's do more with our current user data--let's say we have a couple more data point about our users, let's say this is part of a social media application, so we have their total number of posts and when they were last active. So let's update our user object:

const user = {
  first: "Mark",
  last: "Zuckerberg",
  totalPosts: 104,
  lastActive: "yesterday",
};

And using this data, we want to create a function that better displays this data, for example in their profile page, so let's call this new function formatUser, and we'll make it an arrow function:

const formatUser = () => {};

And once again, it will accept the user object, and in the parameters, we'll destructure all of the properties:

const formatUser = ({ first, last, totalPosts, lastActive }) => {};

And we're going to return our data on not a string this time, but an object, which will have two properties: username and activity. For username, we'll concatenate first and last, and for activity, we'll say X posts total, last active etc:

const formatUser = ({ first, last, totalPosts, lastActive }) => {
  return {
    username: `${first}${last}`,
    activity: `${totalPosts} posts total, last active ${lastActive}`,
  };
};

So we're returning an object, but we're having to do so explicitly. Is there a more concise way to return an object from an arrow function implicitly?

There is. All we have to do is remove the return statement, as well as the function body and almost exactly like our destructured parameters, we wrap a set of parentheses around the object we want to return. This brings back our implicit return and again cuts down a couple lines of code in the process:

const formatUser = ({ first, last, totalPosts, lastActive }) => ({
  username: `${first}${last}`,
  activity: `${totalPosts} posts total, last active ${lastActive}`,
});

And if we wanted to, we could try to stuff all of this on a single line to make it even more concise, but that thought should give us a moment of pause.

When it comes to using these techniques that we've gone through that help make our code more succinct and to the point, be mindful that you don't go too far and use too many of these at once. It may be easier to write less code, but ultimately it is best to write code that is easy to read, both for yourself and others.

So just because you can in many cases doesn't mean you should. With that said, we can trim down a lot of repetitive code by using arrow functions with their implicit return and parameter destructuring.