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

Yamcha's Power Level

When JavaScript reaches the end of a function that has no explicit return, it returns undefined .

The translatePowerLeveloffice 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 .

ewaltandured.blogspot.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

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel