Welcome to the Treehouse Community
Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.
Looking to learn something new?
Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.
Start your free trialac10
12,799 PointsDestructuring functions
I'm confused about this part of the lesson.
function getData({ url, method = 'post' } = {}, callback) {
callback(url, method);
}
getData({ url: 'myposturl.com' }, function (url, method) {
console.log(url, method);
});
Which part of this code is the "destructered" part? i.e. What would it look like if it weren't destructered?
Also, why is there an empty set of brackets within the list of parameters here?:
function getData({ url, method = 'post' } = {}, callback) {
callback(url, method);
}
What does it mean? It wasn't explained in the video:
3 Answers
akak
29,445 PointsThe empty brackets there is the part of the syntax to allow deconstruction of an object. Look closely how the getData function is being called. It get's only two arguments: an object with url key, and a callback function.
Based on that fact, without using deconstructing (and just to stay ES5 all the way also with the old way of supplying default arguments) this function would look like this:
function getData(data, callback) {
data.method = data.method || 'post';
callback(data.url, data.method);
}
But since we know data will be an object with keys url and method we can destructure it using {url, method} = {}
. And now access directly url and method keys without doing data.url
, data.method
.
EDIT: As correctly pointed out by Tom Geraghty in the comments, the = {}
part is not required in deconstructing. It's only a safeguard that provides {}
as the default value if the function is called with the first argument as undefined
. It's totally optional, and the deconstruction will work fine as described without it as well.
Tatiana Vasilevskaya
Python Web Development Techdegree Graduate 28,600 PointsDon't empty brackets in { url, method = 'post' } = {}
mean that the default value is {}
and they are not part of destructuring syntax?
Tom Geraghty
24,174 PointsThe highest voted answer doesn't seem correct. The ={} is setting the default values as OPTIONAL for the function to be called. So you can call the function like this:
getData({}, callback);
or this:
getData({url: things, method: stuff}, callback);
Without the ={} in the parameter, if you called it the first way getData({}, callback)
you would get an error.
Read the linked article by Loris Guerra here especially:
The way to circumvent this function call error is to set a default value for the configuration object itself:*
function myFunc({name = 'Default user', age = 'N/A'} = {}) { }*Emphasis mine
Ken S.
3,838 PointsHi Tom,
Your effort to explain this for us is appreciated, however it seems there is little point to adding the default value of an empty object here.
When the function is called in the way you suggest: getData({}, callback);
The function does NOT fail even with the default value removed, because you are providing the exact same argument as would have been default, so even if the default is missing from the function, you are still running the function using the exact same arguments.
Thats why this seems pointless to me in this example and even more confusing because it is not explained in the video. The only way this seems to do anything is if you called getData in this way:
getData(undefined, callback);
But if you are going to call it in this way, you might as well type the {} in place of the undefined and get the exact same thing. I understand if the first argument is the only argument in a function, but otherwise it just seems completely pointless to me. Can an experienced dev chime in and settle this once and for all?
akak
29,445 PointsKen,
Tom is right with the explanation of how this works. And you are also right that the only case that would get handy is when you call the function like getData(undefined, callback)
. But this is a more common case than one might expect.
This is a very basic example to illustrate this:
const users = [
{name: 'Mark', age: 22, active: false},
{name: 'Karen', age: 21, active: true},
{name: 'Andy', age: 30, active: true}
]
function getActiveUsersDetails({name, age, active} = {}, callback) {
if (!name) {
callback('No such user', null);
} else if (!active) {
callback('User is inactive', null);
} else {
callback(null, {name, age})
}
}
function getUser(name) {
const user = users.find(user => user.name === name);
getActiveUsersDetails(user, (error, data) => {
if (error) {
console.warn(error);
} else {
console.log(`User ${user.name} is active. Her/his age is ${user.age}`)
}
});
}
getUser('Mark');
getUser('Karen');
getUser('a_guy_thats_not_on_the_list');
Array.find
returns either element or undefined. So in case when it returns undefined the first parameter to our function would be... wel undefined
:) If you remove ={}
in the getActiveUsersDetails
the third call to the function to get a_guy_thats_not_on_the_list
would fail with TypeError
.
You could, of course, do a guard in getUser
function like:
if (user) {
getActiveUsersDetails(user);
} else {
console.warn('No such user');
}
so getActiveUsersDetails
would not be called with undefined. But it all depends on your implementation and when do you want this check to happen. I think it's a good idea to guard the getActiveUsersDetails
function with default ={}
so it never crashes with TypeError. Since you might be reusing it a lot in different places and writing each time a guard might be not the best solution.
Here's jsBin if you want to play with this a bit yourself.
Hope this helps and clears things a bit. Cheers!
Ken S.
3,838 Pointsakak,
Its helpful! Thank you!
Loris Guerra
17,536 PointsHere is a complete explanation that helped me.. https://simonsmith.io/destructuring-objects-as-function-parameters-in-es6/
ac10
12,799 Pointsac10
12,799 PointsGot it, thanks very much!