Angular 4 Cannot Read Property Errors of Undefined
As a JavaScript developer, I'm sure you've encountered the frustrating runtime TypeError Cannot read properties of undefined
.TypeScript gives you lot 2 ways of interpreting naught
and undefined
types, too known equally Blazon Bank check Modes, and ane of them tin avoid this easily disregarded TypeError.
Until TypeScript 2.0, in that location was but ane blazon bank check mode - regular - and it considers null
and undefined
every bit subtypes of all other types. This means null
and undefined
values are valid values for all types.
TypeScript 2.0 introduced Strict Type Check Mode (as well referred to equally strict zip checking mode). Strict Type Check differs from Regular Type Bank check because information technology considers nothing
and undefined
types of their own.
I'll prove you how Regular Type Check handles undefined
(the same applies to null
) and how Strict Type Check prevents you lot from introducing unwanted behavior in our lawmaking, similar that infamous TypeError Cannot read properties of undefined
.
When undefined becomes a problem
The part translatePowerLevel below takes a number every bit argument and returns strings ane
, two
, many
or it's over 9000!
.
function translatePowerLevel(powerLevel: number): string {
if (powerLevel === 1) {
return 'one';
}
if (powerLevel === ii) {
render 'two';
}
if (powerLevel > 2 && powerLevel <= 9000) {
return 'many';
}
if (powerLevel > 9000) {
return 'it\'s over 9000!';
}
}
However, this lawmaking doesn't handle 0, a valid input - yeah, looking at you, Yamcha.
Yamcha's Power Level
When JavaScript reaches the end of a function that has no explicit return, it returns undefined
.
The translatePowerLevel
office return value is typed explicitly as string
, but it is possibly also returning undefined
when the argument powerLevel
has the value0. Why is TypeScript not triggering an error?
In Regular Blazon Cheque Mode, TypeScript is enlightened that a function might return undefined
. Only at the same time, TypeScript infers the return type to exist only of type string
because TypeScript is widening the undefined
type to string
type.
As another example, if you lot assign null
or undefined
to variables while in Regular Type Check Style, TypeScript will infer these variables to be of type any
.
const coffee = null;
const tea = undefined;
Interpreting undefined
or null
as subtypes of all other types can lead to runtime issues. For instance, if you attempt to get the length of the result of translateNumber(0)
, which is undefined
, JavaScript will throw this TypeError at runtime: Cannot read properties of undefined (reading 'length').
const powerLevel = translatePowerLevel(0); // undefined
console.log(powerLevel.length); // Uncaught TypeError: Cannot read properties of undefined (reading 'length')
Unfortunately, TypeScript'due south Regular Type Check Way is non able to alert y'all to when y'all may have made that fault.
Strict Blazon Check Mode to the Rescue
Strict Type Check Fashion changes how TypeScript interprets undefined
and cypher
values. But commencement, permit's enable Strict Type Bank check Way.
How to Enable Strict Blazon Bank check Fashion in TypeScript
In the root of your project, at that place should be a tsconfig.json file
. This is the TypeScript's configuration file and you can read more than nigh it here.
// tsconfig.json example
{
"compilerOptions": {
"module": "system",
"noImplicitAny": true,
"removeComments": true,
"preserveConstEnums": true,
"outFile": "../../built/local/tsc.js",
"sourceMap": truthful
},
"include": ["src/**/*"],
"exclude": ["node_modules", "**/*.spec.ts"]
}
Inside compilerOptions
property, all we need to practise is add the property "strictNullChecks": true
.
It volition expect something like this:
// tsconfig.json
{
"compilerOptions": {
"module": "organization",
"noImplicitAny": true,
"removeComments": true,
"preserveConstEnums": true,
"outFile": "../../built/local/tsc.js",
"sourceMap": true,
"strictNullChecks": true
},
"include": ["src/**/*"],
"exclude": ["node_modules", "**/*.spec.ts"]
}
At present that nosotros have switched to Strict Type Check Mode, TypeScript throws this error for translatePowerLevel
function: Function lacks catastrophe return argument and return blazon does not include 'undefined'
.
That error message is telling you the part is returning undefined
implicitly, but its return type does not include undefined
in information technology.
Awesome! TypeScript is now aware the render type does non match all possible render values, and this could lead to problems at runtime! Simply how tin can you match the render type to all possible render values?
You lot can either add a return statement so the function e'er returns a string
(solution #i), or alter the return type from cord
to string | undefined
(solution #2).
Friction match All Possible Return Values: Solution #1
Calculation a return statement so it is e'er explicitly returning a value - in the code below, information technology is now returning the cord zero
.
// Solution #1: add together a render statement so it always returns a cord
part translatePowerLevel(powerLevel: number): cord {
if (powerLevel === 1) {
return 'one';
}
if (powerLevel === 2) {
return 'two';
}
if (powerLevel > 2 && powerLevel <= 9000) {
render 'many';
}
if (powerLevel > 9000) {
render 'information technology\'southward over 9000!';
}
// new render statement
return 'zero';
}
Match All Possible Render Values: Solution #2
Make the undefined
return type explicit so wherever translatePowerLevel
is used, you have to handle nullish
values as well.
// Solution #two: return type as string | undefined
function translatePowerLevel(powerLevel: number): string | undefined {
if (powerLevel === 1) {
render 'one';
}
if (powerLevel === 2) {
return 'two';
}
if (powerLevel > 2 && powerLevel <= 9000) {
return 'many';
}
if (powerLevel > 9000) {
render 'it\'south over 9000!';
}
}
If you were to compile the following code again using Solution #2, TypeScript would throw the mistake Object is perhaps 'undefined'
.
const powerLevel = translatePowerLevel(0); // undefined
console.log(powerLevel.length); // Object is possibly 'undefined'.
When y'all cull a solution like Solution #two, TypeScript expects you to write code that handles possible nullish
values.
There's no reason not to use Strict Type Cheque Mode
Now you understand how TypeScript interprets null
and undefined
types and how you can migrate your project to Strict Mode.
If you are starting a new project, you should definitely enable Strict Type Check Fashion from the beginning. And in instance you will migrate from Regular to Strict Blazon Bank check, our team tin assistance with strategies to practice then in a less painful way.
At Bitovi we highly recommend using - or migrating to - Strict Type Bank check Mode for Athwart application development, as information technology tin help you produce improve, more reliable lawmaking. If you need help with building amazing web apps feel free to achieve us at bitovi.com .
Source: https://www.bitovi.com/blog/how-to-avoid-the-infamous-cannot-read-properties-of-undefined-with-typescript
0 Response to "Angular 4 Cannot Read Property Errors of Undefined"
Post a Comment