Most user interfaces have some kind of list. Whether it’s a display of data returned from an API or simply a drop-down list in a form, lists have become a cornerstone element in web applications. It is common to map over a set of data to render these lists, and bugs will inevitably occur.
As a result, the TypeError Cannot read property 'map' of undefined is very common and one of the first errors that developers will be confronted with. It occurs when the variable being executed is of a different type than expected. Recognizing the error and the root cause will save you valuable time in the long run.
In this article, you’ll learn about the TypeError Cannot read property 'map' of undefined, how it happens, how it can be fixed, and what you can do to mitigate this error in the future.
Understanding why they happen will reduce the time needed to debug and fix them. These errors will stop the execution of a program and, therefore, will be detrimental to the user experience if they are not dealt with - errors can cause an application or UI code to crash, resulting in an error pages, blank spaces or blank pages in your application.
In this section, you’ll discover what causes the TypeError Cannot read property 'map' of undefined and how to prevent it.
This is what makes TypeErrors so common. They can happen any time a value or variable is used, assuming that value is one type when it is actually another.
In the case of map, this method lives on the Array prototype. So calling map on anything other than on an Array will throw a TypeError.
The TypeError Cannot read property 'map' of undefined occurs in the following situations:
In a perfect world, APIs would be consistent. They would always return the requested data in the desired format. In this scenario, they would be easy to parse and never change.
Unfortunately, in the real world, APIs can be inconsistent. The response might be in a different format than you expected, and if you don’t add some checks, your code could run into some issues.
Here is an example using Nationalize.io, an API predicting the nationality of a name passed as a parameter:
In the second fetch, there is no country key in the data object, making it undefined``. Calling the map` function on it throws a TypeError.
Developers are humans and, therefore, make typos. Similar to the previous example, if you access a property that doesn’t exist on an object, the value will be undefined. Calling the map method will throw the TypeError Cannot read property 'map' of undefined:
It’s easy to make a call and forget to take into consideration whether it’s an asynchronous one. When a value is populated asynchronously, accessing it too early will result in an error, as the value might still be undefined:
The result of this code is the console logging on line 12 will execute before the fetch call is done and, therefore, before the one on line 5. At this point, countriesData is undefined, and calling map on it would throw an error:
The asynchronous aspect is something that React developers have to be particularly wary of. Children components will inherit data through props from their parents, but if the parent isn’t done fetching or computing the necessary data before the child starts rendering, this will also throw an error:
The first thing you can do to mitigate this error is to use TypeScript. This strongly typed programming language will warn you ahead of time if you use an unacceptable type:
The second way you can mitigate the error is through conditional checks to ensure the value is available before trying to use it. It’s particularly helpful in React, wherein developers regularly use conditional rendering to avoid undefined variables.
Using the previous library and books example, here is a way to use conditional check and rendering but only when set:
The third solution is optional chaining. This simple operator will short-circuit and return undefined if you call a function on a property that doesn’t exist:
Finally, you can wrap your call in a try-catch block. You can read more about try-catch here. In the case of API calls that may fail and return error messages, like the first example, you can also use a catch() after your then () function to handle errors.
For this situation, libraries such as Axios are preferred over fetch, as the latter will only throw an error on network issues and not on API errors (such as a 500). Axios, on the other hand, comes with error handling:
You can read more about Axios vs. Fetch here.
Over the years, each developer builds a little toolkit of tips and tricks to help them accomplish their job quicker. Keeping in mind all the possible solutions listed in this article will speed up your development and reduce the time spent hunting 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.