In this article, you'll learn about the Cannot read property of '0' of undefined error, when it can occur, and how to mitigate it.
However, the elements of the array become properties themselves. In the same way that length is a property, the first element becomes the 0 property, the second element becomes the 1 property, and so on:
This means accessing the first element with arr is the same as accessing the 0 property of arr. If you try to access the first element of a variable that is supposed to be an array but is actually undefined, you will get the dreaded Cannot read property '0' of undefined error.
The same error can occur for array-like objects as well. Array-like objects are objects that support the subscript () operator (ie a string).
Gecko (in Firefox) gives this error: TypeError: XXX is undefined. n older versions of the v8 engine (in Chrome, Chromium, and Node.js), the error message reads like this: Cannot read property '0' of undefined. It was recently modified to read TypeError:Cannot read properties of undefined (reading '0') in newer versions of v8. This means that in modern Chrome, Chromium-based browsers, and Node.js, you should see TypeError: Cannot read properties of undefined (reading '0').
Leaving this error unchecked can be very detrimental to the user experience because it can lead to bugs or crashes. However, this error is easy to fix once you have pinpointed the exact reason your variable is undefined.
From the previous discussion, it's clear that the cause of the Cannot read property '0' of undefined error is the array being undefined. There are multiple reasons why an array can be undefined, including the following"
The most common mistake that leads to a Cannot read property 0 of undefined error is forgetting to initialize the array when declaring it. An uninitialized variable will be undefined by default, and trying to access its elements will throw the Cannot read property '0' of undefined error:
If a property of an object is an array, it's possible to accidentally misspell the key or try to access the array through the wrong key. A nonexistent key in an object returns undefined; thus, trying to access its elements throws the Cannot read property '0' of undefined error.
For example, consider the following object where marks is an array:
You can access the marks array using student.marks or student["marks"]. But if you misspell "marks", it returns undefined:
If you're not careful and try to access the element of the array, you'll get the Cannot read property '0' of undefined error:
Here, matrix is an array of four elements, each of which is an array of three elements. You can access an individual entry by specifying the index of that entry with respect to both the outer and inner arrays.
For example, matrix is the first entry of the first array:
Essentially, matrix returns the first array whose first entry is then accessed using . If the first index is out of bounds, it returns undefined. Trying to further access its element throws an error:
In the earlier snippet, matrix is undefined, so trying to access its element throws the Cannot read property '0' of undefined error.
It's a common practice to populate an array by calling a function. However, you must make sure that the function is actually called. Not doing so may result in the array being undefined.
In the following example, the populate function is responsible for populating the array, but it's not being called. Thus, arr is undefined, and when arr is accessed, it causes the Cannot read property '0' of undefined error:
In the following code, the function foo accepts one argument, but none are passed, resulting in data being undefined and the Cannot read property '0' of undefined error:
A common pattern in programming is to assign a variable with a value that depends on some condition. In this case, care must be taken to ensure all the possible cases have been taken care of; otherwise, the variable may be undefined and cause errors.
Consider the following function that populates the marks array based on the name parameter:
The function will work fine if the name is either Bob or Alice. However, any other name (or even misspelling Bob or Alice) will throw the Cannot read property '0' of undefined error:
A very common case, especially when dealing with asynchronous processes, is falling victim to the so-called race condition. A race condition occurs when there's no definite order of completion of multiple processes, and depending on the order, undesirable things can happen.
For example, suppose you're populating an array in an async function. If you try to access the array before the array is populated, you'll get the Cannot read property '0' of undefined error:
In the previous code snippet, the populate function is an asynchronous function that populates the array. In the code, setTimeOut is used to simulate a delay of two seconds for the purpose of demonstration. In practice, this could be a delay caused by having an API call, reading from a file or a database, or waiting for user input. This means that the console.log statement is executed before the array is populated. At that point, the array is still undefined, and it throws the Cannot read property '0' of undefined error.
No matter what application you're developing, it's likely that you'll be depending on some external services. This could be an API, a database, a file, or a user input. Apart from the possibility of creating a race condition, these external services can also create problems if their structure changes.
If you're populating an array from the response of an API call, it can be undefined due to various reasons, including the following:
For example, consider the following API call where an array is populated from the items field of some API:
If the items field is undefined, the previous code will throw the Cannot read property '0' of undefined error. If a new version of the API removes the items field, accessing data.items will return undefined and accessing elements will throw the Cannot read property '0' of undefined error.
Unfortunately, there's no one-size-fits-all solution to mitigating the Cannot read property '0' of undefined error. However, the following are some of the ways you can try and prevent it:
Have you forgotten to initialize the array? Have you made a typo somewhere? Have you forgotten to call the function that populates the array? These are some of the common mistakes that can cause the Cannot read property '0' of undefined error.
It's a good idea to go through your code and try to look for these common mistakes. Most often, you'll find an issue in your code, and you can quickly fix it. You can also use a linter like ESLint to catch some very common errors, like misspelled variables or function names.
To prevent the Cannot read property '0' of undefined error, you can check whether the array is undefined before accessing it, and there are multiple ways to do so.
A very common solution (that is highly recommended) is to check whether the type of a variable is undefined or not:
However, the problem with this solution is that if a variable is nonexistent, typeof still returns undefined. While this might seem like a useful feature since it prevents you from accessing nonexistent variables, relying on this behavior is not a good practice. If you're trying to access a nonexistent variable, it indicates a bigger problem with your code, and you want to catch this error instead of suppressing it.
To solve this, you can check for undefined using the comparison operators:
If the variable is not defined, it will throw a ReferenceError:
However, just because the variable is not undefined doesn't mean that you're safe. It could still be null. In addition, there's no guarantee that it's an array or that it has the index you're trying to search for. In this instance, the recommended practice is to use the Array.isArray method to check whether the variable is an array or not and check its length before accessing elements. As an added bonus, Array.isArray() also checks if the variable is undefined or null or not, and it throws a ReferenceError if it's not defined:
This method, however, does not work for array-like objects because they are not an Array. While there are methods that work for all arrays and array-like objects, they can be complicated. It's often easier to simply check for the particular array-like types that you're actually using.
This is the easiest solution to mitigate the Cannot read property '0' of undefined error. You can also use it to check if an argument of a function is undefined or not. However, this solution only prevents the code from crashing if an array is undefined, and it doesn't prevent the array from being undefined in the first place. If you have a lot of arrays, checking them every time you want to access them can be tedious and error-prone.
If you don't want to deal with type-checks at every location where an array is accessed, try TypeScript. TypeScript will type-check your variables for you and will simply refuse to compile if an array is undefined (unless you explicitly allow it to):
This code will refuse to compile with the error Type 'undefined' is not assignable to type 'number'.
Another strategy to make sure the array isn't undefined is to provide an alternative value when the array is undefined. You can use the logical OR (||) operator to retain the original value if the array isn't undefined or provide a default value if the array is undefined:
This code can be shortened by using the ||= operator:
This method is useful if you have predefined default values to assign. For example, in an application, you may set some default configuration if the user doesn't provide any custom configuration.
The optional chaining operator (?.) is a safe way to access the properties of an object without throwing an error if the property is null or undefined. An expression involving the optional chaining operator returns undefined if any one reference is missing (null or undefined). This makes it easier to write code because you don't have to check for undefined or null at every level:
This method works best in cases where the structure of the object isn't guaranteed; for example, in an API response.
Using const instead of let or var is a good practice. It's also a good idea to use const whenever you're dealing with a variable that you don't intend to change. A const variable also forces you to assign an initial value to it so that it's never unintentionally undefined:
It will also make sure an array doesn't accidentally (or intentionally) get assigned undefined during the lifecycle of the code:
Using const, however, means that you lose some of the flexibility of let and var. For instance, it's not possible to populate an array by assigning a value to it. The following code will not work with const:
You can work around it by initially declaring the variable as an empty array and later adding elements to it:
This works because while const doesn't let you reassign the array, it lets you modify the elements of the array.
If you need to reassign the array in multiple places, it's better to use let, as it becomes cumbersome with const. However, if you're sure you won't modify the array, choose const.
To prevent race conditions between background processes, pay extra attention to the order in which the processes are executed. To make sure an array isn't accessed before it's initialized, use async/await and promises:
In the previous code, you must wait for the populate() function to finish executing before you can use the access() function to access the array:
The try...catch block is used to catch run-time errors or exceptions. If the code inside the try block throws an error, the error is passed to the catch block for handling. If no error is thrown, the catch block will not be called:
Although using a try…catch prevents the error from crashing the application, it's merely hiding the symptom, not the cause. If your code is trying to access an array that is undefined, it indicates an issue somewhere else, and it's better to explicitly check for undefined using an if statement, as explained previously.
However, in cases where you want to halt the execution of the rest of the program upon encountering an error or you have multiple places in the code that can throw an error, try…catch is a good choice.
The Cannot read property '0' of undefined error can be avoided during software development by adopting some best practices. In this article, you learned why this error happens and how to mitigate it by always ensuring that the array you are trying to access is not undefined.
Meticulous can help you catch these bugs before they get to your users in production. Remember, you need to use the right approach for the right situation. This will help you write better code and reduce the risk of bugs.
Meticulous is a tool for software engineers to catch visual regressions in web applications without writing or maintaining UI tests.
Inject the Meticulous snippet onto production or staging and dev environments. This snippet records user sessions by collecting clickstream and network data. When you post a pull request, Meticulous selects a subset of recorded sessions which are relevant and simulates these against the frontend of your application. Meticulous takes screenshots at key points and detects any visual differences. It posts those diffs in a comment for you to inspect in a few seconds. Meticulous automatically updates the baseline images after you merge your PR. This eliminates the setup and maintenance burden of UI testing.
Meticulous isolates the frontend code by mocking out all network calls, using the previously recorded network responses. This means Meticulous never causes side effects and you don’t need a staging environment.
Learn more here.
Meticulous is a tool for software engineers to catch visual regressions in web applications without writing or maintaining UI tests. Meticulous isolates the frontend code by mocking out all network calls, using the previously recorded network responses. This means Meticulous never causes side effects and you don’t need a staging environment.
Set up in minutes and generate tests to cover your whole application.