Using FP to prevent ‘Cannot read property of undefined errors’ (A.K.A. Array.reduce rocks)

‘Cannot read property of undefined errors’ are common when using JavaScript or TypeScript.  While some languages, such as CoffeeScript, have the existential operator which checks for the existence of an object, it doesn’t currently exist in JavaScript.

This means the following will throw an exception:

 const myObject = {};
  const zipcode = myObject.homeOwner.address.zipcode;

Of course it’s easy to see in this example.  However, if you receive myObject from a REST service call and it may not return the full object, it’s easy to miss.

The first approach to resolving this is typically:

let zipcode = {};
if (myObject && myObject.homeOwner
   && myObject.homeOwner.address) {
    zipcode = myObject.homeOnwer.address;
  }

Of course, this becomes very cumbersome and obfuscates what you’re really trying to do. Functional programming techniques can provide shortcuts for preventing these kinds of errors.  This is where Array.reduce comes to the rescue:

let _ = function (instance, path) {
  return path.split('.').reduce((p, c) => p ? p[c] : undefined,instance);
}

let zipcode = _(myObject,'homeOwner.address.zipcode');

Super cool!  This 1-line function splits the path parameter into an array of accessors and uses reduce to iterate through them and either return undefined or the value of the final property.

Check out the safe-get github repo or npm package for more info, tests and examples.

TL;DR

Functional programming rocks.  Use safe-get

4 Replies to “Using FP to prevent ‘Cannot read property of undefined errors’ (A.K.A. Array.reduce rocks)”

  1. Hi there, I believe your website might be having internet browser compatibility problems.
    When I take a look at your site in Safari, it looks fine however when opening in Internet Explorer, it’s got some overlapping issues.

    I merely wanted to provide you with a quick heads up!
    Aside from that, excellent site!

Leave a Reply

Your email address will not be published. Required fields are marked *