/home

How to avoid "Cannot read property 'name' of undefined" in JavaScript

When working with JavaScript you will sooner rather than later get a TypeError: Cannot read property 'name' of undefined (or TypeError: something.name is undefined or similar). This happens when you try to access a property of a value that is undefined (or similarly for values that are null). Here is an example:

var obj = {};
obj.hello.world; // Uncaught TypeError: Cannot read property 'world' of undefined

There are some ways around this. One approach that is simple and works well for small chains of properties is using the logical AND operator &&.

obj.hello && obj.hello.world; // short and quite OK
obj.a && obj.a.lot && obj.a.lot.of && obj.a.lot.of.properties // gets ugly very quickly

When some things can go wrong in your code, you usually use try/catch blocks. You can do the same when accessing properties as you can see below.

try {
    obj.a.lot.of.properties;
} catch (exception) {
    // do something else
}

But scattering many try/catch blocks throughout your code just to access properties is neither practical nor readable. It is ugly. A nice shortcut is using a simple helper function that does nothing else but calling a provided function in a try/catch block. Using ES6 arrow functions, you can call that helper function with a one-line callback (or more accurately, a closure) function that just returns the property you want.

function getSafe(fn) {
    try {
        return fn();
    } catch (e) {
        return undefined;
    }
}

// use it like this
getSafe(() => obj.a.lot.of.properties);

That way, you will either get the property value or undefined. That works because JavaScript only evaluates the content of the inner callback (or closure) when it is actually executed. So it will only be evaluated inside of the try/catch block and not yet in the code calling the helper function.

PS. In some programming languages, there is also a thing called elvis operator ?. and the dirty example from above would like this obj?.a?.lot?.of?.properties using it. However, there is no such thing as an elvis operator in JavaScript (or TypeScript).