# 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

# Resources


Related Tidbits