DEV Community

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

Collapse
 
aminnairi profile image
Amin

Until you have a property named _ that you can't access anymore.

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

console.log(safeGet(obj).user._.toys[0].price._);
// TypeError: Cannot read property '0' of undefined
Thread Thread
 
dividedbynil profile image
Kane Ong • Edited

Thanks for pointing out, feel free to try this.

function safeGet (obj, end='_') {
  return new Proxy({}, {
    get(_, prop) {
      if (prop == end)
        return obj
      const next = typeof obj == 'undefined' ? obj : obj[prop]
      return safeGet(next, end)
    }
  })
}

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

console.log(safeGet(obj, 'end').user._[0].toys[0].price.end); // 1999
console.log(safeGet(obj, 'end').user._.toys[0].price.end); // undefined
Thread Thread
 
aminnairi profile image
Amin

This API looks very sexy, don't get me wrong, but it has some flaws:

  • You would have to know 100% of all the properties of the object to search the properties from, this is not always possible, especially from large code-bases.
  • If you use an object from an untrusted source or an API, nothing guarantees that you won't get something different tomorrow, and this could crash your application if you are using the same end as one of the property of this API.
  • Even if you handle the JavaScript exception thrown from accessing a bad index, this totally blocks the user from getting the expected behavior, while the solution provided by the OP (and some other libraries like Lodash) would work as expected.

But if you are using an object from a trusted source, then your solution is very elegant.

Thread Thread
 
dividedbynil profile image
Kane Ong • Edited

You would have to know 100% of all the properties of the object to search the properties from, this is not always possible, especially from large code-bases.

This claim is false, no matter the size of code-bases, you always have to know where to access the right field in that JSON. Knowing the JSON field location already avoided a bad ending.

If you use an object from an untrusted source or an API, nothing guarantees that you won't get something different tomorrow, and this could crash your application if you are using the same end as one of the properties(your typo) of this API.

The origin of the problem above comes from the untrusted source, not my provided solution. Optional chaining can't solve it either.

Reminder: All of my solutions do avoid crashing from accessing bad indices.

Even if you handle the JavaScript exception thrown from accessing a bad index, this totally blocks the user from getting the expected behavior, while the solution provided by the OP (and some other libraries like Lodash) would work as expected.

Optional chaining is the topic of this article, which means no exception is thrown from accessing a bad index. Have you tried to access a bad index from my solutions yet? It behaves as expected.