Split() is a JavaScript string method that splits a string into an array of substrings without mutating the original string. As a JavaScript developer, there's a good chance that you've used the split() method and encountered this error: "Cannot read property split of undefined".
This error is a TypeError , and it occurs when calling a method, operand, or argument on the wrong data type, or when calling the split() method on a variable that returns undefined. A TypeError is one of the most common errors in JavaScript and so it's important to understand why it happens and how to avoid it.
In this article, you'll take a closer look at the meaning of the error "Cannot read property split of undefined", what causes it, some examples, and techniques to prevent it.
Why is it Important to Understand this Error As a developer, you're constantly dealing with user inputs as strings. Understanding this error will enable you to work with strings more effectively and will help prevent your users from having a bad experience with your application.
What Causes "Cannot Read Property Split of Undefined" The split() method divides a string into an array of substrings based on the separator argument passed in. Let's look at a few code examples below:
const sampleString = "This is a sample string";
Call the split() method on the string:
After running this code in your console, you'll see the split() method in action:
['This', 'is', 'a', 'sample', 'string']
The split() method can be a very useful tool in algorithms involving string data types. For example, you could use it when you need to reverse a string, or remove spaces from within a string.
The error "Cannot read property split of undefined" can occur when performing any of these types of operations if the variable is undefined. Furthermore, when you are working on a project, there are several other scenarios where this error can occur, including the following:
If different values are assigned to a variable several times, calling the split() method on the variable when it is set to undefined will result in the error. For example, a variable is defined as a string in a global scope and set to undefined in the function scope. In this case calling the split () method on the variable in the function scope will result in an error. In cases where the return value of a variable could be a string or undefined, the function could return undefined, and thus calling split on the output might result in an error. Let's look at a concrete example. Suppose you'd like to return a message depending on the value of n. The variable, message, is initialized on the first line. When n is greater than five, the message is ‘This number is greater than five’, and the Split() method is called on the message.
function greaterThanFive(n) {
let message;
if (n > 5) {
message = 'This number is greater than five';
return message.split(' ')
} else {
return message.split(' ');
}
}
console.log(greaterThanFive(6));
The output will be:
[ 'This', 'number', 'is', 'greater', 'than', 'five' ]
The value of the message when n is less than five is not defined. As such, when n is less than five, the split function will be called on the undefined message, which will return an error. For example, calling greaterThanFive(4) will throw an error, as can be seen in the screenshot:
If you're dealing with JavaScript promises and you are trying to access the response from the promise without awaiting it, if the split() method is called on this response, this error would be generated. This is because when the response is accessed, the promise is unresolved and as such the response will be undefined. How Can you Fix this Error Now that you understand why this error occurs and its potential impact on your work, how can you avoid it? There are several ways of doing this.
Check Data Types Check the data type of your variable before proceeding to call the split() method. If the data type is a string, then you can proceed with your splitting operation. You can check a data type using the typeof() method, then call the split() method using conditional statements like if and else, as shown in the following code:
const sampleString = "This is a sample text";
if (typeof(sampleString) === 'string') {
return sampleString.split('');
} else {
return sampleString;
}
The first line in the code snippet defines the sample variable you want to check with the conditional statement in the next line. If the conditional if statement is true, then the sample variable is split; if it returns false, then the algorithm returns the original variable. This is a simple, easily added check to catch and address the Cannot read property split of undefined error.
Another way to implement more thorough type checks in your code is to use TypeScript. TypeScript is a strongly typed superset of JavaScript that allows you to catch type errors at build time rather than at runtime. For example, a function written in TypeScript might look like this:
// note the `string` type specified for the input parameter
const splitString = (input: string) => {
return input.split('');
}
console.log(splitString('foo')); // [ 'f', 'o', 'o' ]
console.log(splitString(undefined)); // Argument of type 'undefined' is not assignable to parameter of type 'string'.
When using TypeScript, you're able to annotate your code with types the way you would in other strongly typed languages. This enables deeper levels of IntelliSense and in-editor errors and hints. In this case, assuming you're using a code editor with TypeScript support, the second call to splitString will show you an error directly in your code editor when you try to invoke the function with an invalid type. This can save a lot of time and effort, as it drastically shortens the feedback loop when it comes to type-related errors, allowing you to find and fix them before your code ever runs.
Assign an Alternative Value If the variable the split() method is called on resolves to undefined, you can assign an alternative value to it.
const sampleString = undefined;
const result = sampleString || ‘ ’
return result.split()
Here, the sample variable is declared at undefined in line one. Rather than calling the split method directly on the variable, line two assigns an alternative value so the split operation will execute without error.
Optional Chaining Optional chaining allows you to optionally call the split() method, depending on if a variable is defined or not. If the variable is defined, the function runs as expected; if it's undefined or null, it stops and returns ``undefined`. This is especially useful in situations where the variable is optional, and may or may not be present.
const person = {}; // empty object
const personalDetails = person.location?.address.split('')
return personalDetails // returns undefined
Because the property location is not present in the person object, the code returns undefined.
try and catch Blocks Wrapping your code in a try and catch block . While this method doesn't prevent the error from occurring, it does ensure that if it occurs, it's handled gracefully. This method is especially useful when there are edge cases that cannot be accounted for in your algorithm. You can read more about try-catch in this blog post here .
One of the benefits of the try and catch block is that it allows developers to handle errors seamlessly, and to customize your error messages. Putting your function in a try and catch block would ensure that a simple, easy-to-understand response is returned to the client if an error occurs.
function convertString(sampleString) {
const result = sampleString.split(" ");
return result;
}
let invalidInput;
try {
const parts = convertString(invalidInput);
} catch (error) {
// handle error and display message here
console.log(error);
}
Conclusion In this post, you have seen the many different scenarios that can result in a "Cannot read property split of undefined" error showing up in your application. You've also learned that carrying out data type checks, assigning alternative values to variables, and exception handling with a try and catch block are some of the best ways to handle the error in your project.
Knowing how to handle errors is important, but a better approach is to avoid them altogether. Integrating Meticulous into your CI flow will allow you to easily catch errors before they reach your customers.
Meticulous 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 .