# Prevent Error with Default {}
when Destructuring
When you use destructuring, make sure to set a default value of empty {}
to prevent it from throwing an error!
function hi(person) {
const { age } = person;
}
hi(); // β Ahh, TypeError
function hi(person = {}) {
const { age } = person;
}
hi(); // β
Yay, no errors
# The story behind this tidbit
So this happened to me the other day. Took me forever to debug my code. Then I realized I made a function call and the data that was being passed was undefined. So whenever you write a function that you will be performing destructuring. ALWAYS. I mean always make sure you set a empty {}
to prevent your app from crashing! π€¦π»ββοΈ
# Why does it throw an Error?
This is because you canβt destructure undefined
and null
values
const { age } = null;
age; // TypeError
const { name } = undefined;
name; // TypeError
When you call a function and you forget to pass an argument. The value is by default undefined
.
function hi(person) {
return typeof person;
}
hi(); // undefined
# Other values that won't throw an Error
Here's a list of other values that you can destructure that won't throw an error.
const { emptyString } = '';
const { nan } = NaN;
const { emptyObject } = {};
emptyString; // undefined
nan; // undefined
emptyObject; // undefined
# Community Input
# Optional Chaining Proposal
CJ J.: A similar issue is what lead to the optional chaining proposal
tc39 Proposal: Optional Chaining
# Introducing idx
CJ J.: This is similar to an internal function at Facebook used both in Hack and JavaScript called idx.
idx is a utility function for traversing properties on objects and arrays. It's a library for accessing arbitrarily nested, possibly nullable properties on a JavaScript object.
CJ J.: You pass in a callback and it calls your callback inside a try-catch so that the error doesn't propagate and it just gives you a sentinel value instead.
const obj = {};
const val = idx(obj, _ => _.x.y);
CJ J.: But for correctness, you can't just catch all exceptions. You have to check for TypeError and then make sure it's a TypeError around reading a property of undefined or null. That way your callback can safely throw exceptions of its own types and not have them be accidentally caught by the idx function.
# How the empty {} is useful
@SamHulick: Here's an example why this format is useful. I use this pattern all the time. Sometimes you want to provide options, but the options themselves are completely optional. π This makes it easy to check for specific options without throwing an error about an undefined object.
function printName(name, options = {}) {
let printedName;
if (options.reverse) {
printedName = name
.split('')
.reverse()
.join('');
}
if (options.allCaps) {
printedName = name.toUpperCase();
}
console.log(printedName);
}
printName('Bob'); // undefined
printName('Jorge', { reverse: true }); // egroJ
printName('Samantha', { allCaps: true }); // SAMANTHA
Thanks: @SamHulick