Resources
cannot read property

Cannot read property "abc" of null/undefined

leduyquang753#3761
January 13, 2021
2 minutes read time

When running JavaScript code, a very common error that occurs is:

console.log(someRandomThing.abc)
                            ^

TypeError: Cannot read property "abc" of undefined.

This is a very basic error, yet people who are new to JavaScript (and maybe programming) often either gloss over or misunderstand the problem being presented in their code, and come to The programmer's hangout to seek an explanation.

Causes

Direct cause

When the JavaScript engine complains about "Cannot read property abc of null/undefined", it means that the thing whose property abc is being retrieved is either null or undefined.

$ node
> let someRandomThing;
undefined
> console.log(someRandomThing.abc);
//            ---- Owner ----|Property
Uncaught TypeError: Cannot read property "abc" of undefined.

The most important thing to note here is it's the "owner" that is being null/undefined. A common mistake is to interpret the error message as that the "property" is null/undefined instead.

Possible behind causes

For a variable to come up containing null or undefined (most commonly undefined) so that the "Cannot read property" error can arise later, the code must have done something wrong beforehand. This section lists some common bugs and mistakes.

undefined from nonexistent object property

By default, when accessing an object's property in JavaScript, if the object in question doesn't have such property, it will return undefined as the default. This applies to nonexistent array indices as well.

> let keyMapping = {
    moveUp: "KeyW",
    moveDown: "KeyS",
    moveLeft: "KeyA",
    moveRight: "KeyD"
};
undefined
> keyMapping.mvoeDown
//            ^^ Typo, oops. The object doesn't have key "mvoeDown".
undefined
> let randomNumbers = [16, 57, 3];
//              Index:  0   1  2
undefined
> randomNumbers[3] // ! The array does not have index 3.
undefined

null from failed queries

Some functions, for example getElementById from the browser API, return null if the function failed to find any result matching what is requested. If left unchecked and the returned value is used in other places, the "Cannot read property" error might arise.

<!DOCTYPE html>
<html>
  <body>
    <p id="paragraph-1">Welcome to <i>The programmer's hangout</i>.</p>
    <p id="paragraph-2">
      This is the place for programmers of any skill level to, well, hangout
      with other fellow programmers. Whether you have just written 5 lines of
      code or been a code nerd for 15 years, you are always welcome!
    </p>
    <script>
      let element = document.getElementById("paragraph-3");
      // The one writing this might think this will add another paragraph to
      // the page, which is not how it works.
      // The browser, failing to find any element with ID "paragraph-3" from
      // the page, returns null.
      element.innerText = "When joining, make sure you read the rules.";
    </script>
  </body>
</html>
Uncaught TypeError: Cannot set property "innerText" of null
    at tph-welcome.html:16

undefined from uninitialized variables

When declaring a variable without an initializer, JavaScript defaults the value of the variable to undefined. If nothing else is assigned to it later, the error will show up.

> let payload; // Defaults to undefined.
undefined
> let testValue = 6;
undefined
> if (testValue > 10) payload = { id: 167503, message: "Welcome to TPH." };
// As the condition does not satisfy, "payload" doesn't get assigned
// and remains undefined.
undefined
> console.log(payload.message)
Uncaught TypeError: Cannot read property "message" of undefined.

undefined from missing parameters

If a function accepts a number of parameters, but the calling code passes fewer than that, the missing parameters are defaulted to undefined.

> function getValue(object) {
... return object.value;
... }
undefined
> getValue({ value: 15 })
15
> getValue() // ! No value is given to "object", defaults to undefined.
Uncaught TypeError: Cannot read property "value" of undefined.

Fixing

The way to fix the "Cannot read property abc of null/undefined" error is of course, to make sure what is being retrieved properties from is not either null or undefined. Based on the reason behind the error, the programmer determines how the issue shall be fixed.

Make sure a property exists

Through either checking or reading the documentation for the correct property, one can make sure what is in their hands isn't JavaScript's default undefined.

async function onCommand(channel, arguments) {
    // Assuming the command is not empty and
    // there is always the first argument.
    let commandName = arguments[0];
    switch (commandName) {
        // ...
        case "getUser":
            if (arguments.length < 2)
                throw "Usage: /getUser <username>";
            // It is guaranteed now that "arguments" has at least 2 elements
            // and thus there is an index 1.
            let username = arguments[1];
            let user = await botClient.fetchUser(username);
            channel.send(JSON.stringify(user);
            break;
        // ...
    }
}

Handle a failed query

If a query for something fails and returns null, the programmer needs to make sure that situation is handled properly.

async function getUserID(username) {
  // Assuming "username" is guaranteed to be a string.
  let user = await botClient.fetchUser(username);
  if (user == null) throw "There is no user with that name.";
  // It is guaranteed now that "user" isn't null.
  return user.id;
}

Make sure a variable contains an actual value

By either initializing the variable or guaranteeing the variable will ultimately receive a value, the error won't be able to occur.

let payload;
let rolledValue = Math.random();
if (rolledValue > 0.5) payload = { id: 169323, message: "Welcome to TPH." };
else payload = { id: 173205, message: "TPH has been waiting for you." };
// In either case, "payload" is guaranteed to be assigned an actual value.
botClient.sendMessage(serverJoiner, payload.message);

Make sure a function is called correctly

When calling a function, make sure enough parameters are passed as required, or provide default values for function arguments, if applicable.

function sendEmbed(content, options = { color: "#888", dismissable: false }) {
  let embed = botClient.createEmbed();
  embed.setContent(content);
  embed.setColor(options.color);
  embed.setDismissable(options.dismissable);
  botClient.sendEmbed(embed);
}

sendEmbed("The programmer's hangout: https://theprogrammershangout.com", {
  color: "#763989",
  dismissable: true,
});

sendEmbed("Example site: https://example.com");
// No value is passed to "options" by the caller,
// defaults to the value specified in the function declaration.
Table of Contents