No Optional Chaining? No Problem. Write Your Own deepGet Function!

Nick Scialli (he/him) - Apr 13 '20 - - Dev Community

Optional chaining is great: it allows us to safely access object properties without worrying if they exist:

const user: {
  name: "Bob"
}
const val = user?.pet?.name;
Enter fullscreen mode Exit fullscreen mode

Rather than crashing if pet doesn't exist on user, it'll simply return undefined.

While this is promising, optional chaining is in stage 4 of proposal for the ECMAScript standard, and is therefore not guaranteed to be available unless specifically accommodated in a transpiler you're using.

Rolling Your Own

The good news is we can fairly easily roll our own optional chaining-like function! Let's call it deepGet:

function deepGet(obj, ...props) {
  try {
    return props.reduce((acc, el) => acc[el], obj);
  } catch (e) {
    return undefined;
  }
}
Enter fullscreen mode Exit fullscreen mode

We can see that we try to iterate over all props in our reduce function. If an error is ever thrown, we just return undefined! Let's see it in action:

const obj = {
  user: {
    name: "Joe",
    age: 20,
    pets: [
      {
        name: "Daffodil",
        type: "dog",
        toys: [
          {
            name: "Toughy",
            price: 1999
          }
        ]
      }
    ]
  }
};

function deepGet(obj, ...props) {
  try {
    return props.reduce((acc, el) => acc[el], obj);
  } catch (e) {
    return undefined;
  }
}

console.log(deepGet(obj, "user", "pets", 0, "toys", 0, "price"));
// 1999
console.log(deepGet(obj, "user", "dogs", 0, "toys", 0, "price"));
// undefined
Enter fullscreen mode Exit fullscreen mode

And there you have it, your own safe deepGet function!

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Terabox Video Player