From ac1ed508f71b7435929da848a205453366bd6ff1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=AA=20Duy=20Quang?= Date: Wed, 13 Jan 2021 21:43:26 +0700 Subject: [PATCH 1/5] Added "Cannot read property "abc" of null/undefined." --- .../javascript/cannot-read-property.md | 193 ++++++++++++++++++ 1 file changed, 193 insertions(+) create mode 100644 src/content/resources/language/javascript/cannot-read-property.md diff --git a/src/content/resources/language/javascript/cannot-read-property.md b/src/content/resources/language/javascript/cannot-read-property.md new file mode 100644 index 0000000..0b7ecd5 --- /dev/null +++ b/src/content/resources/language/javascript/cannot-read-property.md @@ -0,0 +1,193 @@ +--- +authors: + - "leduyquang753#3761" +created_at: "2021/01/13" +title: Cannot read property "abc" of null/undefined +--- + +When running JavaScript code, a very common error that occurs is: + +```none +console.log(someRandomThing.abc) + ^ + +TypeError: Cannot read property "abc" of undefined +``` + +This is a very basic error, yet people who are new to JavaScript (and maybe +programming) often either gloss over or misunderstand the problem being +presented in their code, and come to _The programmer's hangout_ to seek an +explanation. + +## Causes + +### Direct cause + +When the JavaScript engine complains about "Cannot read property `abc` of +`null`/`undefined`", it means that the thing whose property `abc` is being +retrieved is either `null` or `undefined`. + +```js +$ node +> let someRandomThing; +undefined +> console.log(someRandomThing.abc); +// ---- Owner ----|Property +Uncaught TypeError: Cannot read property 'abc' of undefined +``` + +The most important thing to note here is it's the "_owner_" that is being +`null`/`undefined`. A common mistake is to interpret the error message as that +the "property" is `null`/`undefined` instead. + +### Possible behind causes + +For a variable to come up containing `null` or `undefined` (most commonly +`undefined`) so that the "Cannot read property" error can arise later, the code +must have done something wrong beforehand. This section lists some common +bugs and mistakes. + +#### `undefined` from nonexistent object property + +By default, when accessing an object's property in JavaScript, if the object in +question doesn't have such property, it will return `undefined` as the default. +This applies to nonexistent array indices as well. + +```js +> let keyMapping = { + moveUp: "KeyW", + moveDown: "KeyS", + moveLeft: "KeyA", + moveRight: "KeyD" +}; +undefined +> keyMapping.mvoeDown +// ^^ Typo, oops. The object doesn't have key "mvoeDown". +undefined +``` + +```js +> let randomNumbers = [16, 57, 3]; +// Index: 0 1 2 +undefined +> randomNumbers[3] // ! The array does not have index 3. +undefined +``` + +#### `null` from failed queries + +Some functions, for example `getElementById` from the browser API, returns +`null` if the function failed to find any result matching what is requested. +If left unchecked and the returned value is used in other places, the "Cannot +read property" might arise. + +```html + + + +

Welcome to The programmer's hangout.

+

+ This is the place for programmers of any skill level to, well, hangout + with other fellow programmers. Whether you have just written 5 lines of + code or been a code nerd for 15 years, you are always welcome! +

+ + + +``` + +```none +Uncaught TypeError: Cannot set property "innerText" of null + at tph-welcome.html:16 +``` + +#### `undefined` from uninitialized variables + +When declaring a variable without an initializer, JavaScript defaults the value +of the variable to `undefined`. If nothing else is assigned to it later, the +error will show up. + +```js +> let payload; // Defaults to undefined. +undefined +> let testValue = 6; +undefined +> if (testValue > 10) payload = { id: 167503, message: "Welcome to TPH." }; +// As the condition does not satisfy, "payload" doesn't get assigned +// and remains undefined. +undefined +> console.log(payload.message) +Uncaught TypeError: Cannot read property 'message' of undefined +``` + +## Fixing + +The way to fix the "Cannot read property `abc` of `null`/`undefined`" is of +course, to make sure what is being retrieved properties from is not either +`null` or `undefined`. Based on the reason behind the error, the programmer +determines how the issue shall be fixed. + +#### Make sure a property exists + +Through either checking or reading the documentation for the correct property, +one can make sure what is in their hands isn't JavaScript's default +`undefined`. + +```js +async function onCommand(channel, arguments) { + // Assuming the command is not empty and + // there is always the first argument. + let commandName = arguments[0]; + switch (commandName) { + // ... + case "getUser": + if (arguments.length < 2) + throw "Usage: /getUser "; + // It is guaranteed now that "arguments" has at least 2 elements + // and thus there is an index 1. + let username = arguments[1]; + let user = await botClient.fetchUser(username); + channel.send(JSON.stringify(user); + break; + // ... + } +} +``` + +#### Handle a failed query + +If a query for something fails and returns `null`, the programmer needs to make +sure that situation is handled properly. + +```js +async function getUserID(username) { + // Assuming "username" is guaranteed to be a string. + let user = await botClient.fetchUser(username); + if (user == null) throw "There is no user with that name."; + // It is guaranteed now that "user" isn't null. + return user.id; +} +``` + +#### Make sure a variable contains an actual value + +By either initializing the variable or guaranteeing the variable will +ultimately receive a value, the error won't be able to occur. + +```js +let payload; +let rolledValue = Math.random(); +if (rolledValue > 0.5) + payload = { id: 169323, message: "Welcome to TPH." }; +else + payload = { id: 173205, message: "TPH has been waiting for you." }; +// In either case, "payload" is guaranteed to be assigned an actual value. +botClient.sendMessage(serverJoiner, payload.message); +``` From 0862031bf964fe7ff0347b5a3bddb0225f0f3bb0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=AA=20Duy=20Quang?= Date: Wed, 13 Jan 2021 21:56:34 +0700 Subject: [PATCH 2/5] Fixed grammar errors. --- .../resources/language/javascript/cannot-read-property.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/content/resources/language/javascript/cannot-read-property.md b/src/content/resources/language/javascript/cannot-read-property.md index 0b7ecd5..437d221 100644 --- a/src/content/resources/language/javascript/cannot-read-property.md +++ b/src/content/resources/language/javascript/cannot-read-property.md @@ -76,10 +76,10 @@ undefined #### `null` from failed queries -Some functions, for example `getElementById` from the browser API, returns +Some functions, for example `getElementById` from the browser API, return `null` if the function failed to find any result matching what is requested. If left unchecked and the returned value is used in other places, the "Cannot -read property" might arise. +read property" error might arise. ```html @@ -129,8 +129,8 @@ Uncaught TypeError: Cannot read property 'message' of undefined ## Fixing -The way to fix the "Cannot read property `abc` of `null`/`undefined`" is of -course, to make sure what is being retrieved properties from is not either +The way to fix the "Cannot read property `abc` of `null`/`undefined`" error is +of course, to make sure what is being retrieved properties from is not either `null` or `undefined`. Based on the reason behind the error, the programmer determines how the issue shall be fixed. From b854b460508fcadcec616fcecab961532261fe87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=AA=20Duy=20Quang?= Date: Thu, 14 Jan 2021 11:55:08 +0700 Subject: [PATCH 3/5] Converted all tabs to spaces. --- .../javascript/cannot-read-property.md | 70 +++++++++---------- 1 file changed, 35 insertions(+), 35 deletions(-) diff --git a/src/content/resources/language/javascript/cannot-read-property.md b/src/content/resources/language/javascript/cannot-read-property.md index 437d221..604b9e8 100644 --- a/src/content/resources/language/javascript/cannot-read-property.md +++ b/src/content/resources/language/javascript/cannot-read-property.md @@ -56,9 +56,9 @@ This applies to nonexistent array indices as well. ```js > let keyMapping = { moveUp: "KeyW", - moveDown: "KeyS", - moveLeft: "KeyA", - moveRight: "KeyD" + moveDown: "KeyS", + moveLeft: "KeyA", + moveRight: "KeyD" }; undefined > keyMapping.mvoeDown @@ -84,22 +84,22 @@ read property" error might arise. ```html - -

Welcome to The programmer's hangout.

-

- This is the place for programmers of any skill level to, well, hangout - with other fellow programmers. Whether you have just written 5 lines of - code or been a code nerd for 15 years, you are always welcome! -

- - + +

Welcome to The programmer's hangout.

+

+ This is the place for programmers of any skill level to, well, hangout + with other fellow programmers. Whether you have just written 5 lines of + code or been a code nerd for 15 years, you are always welcome! +

+ + ``` @@ -143,21 +143,21 @@ one can make sure what is in their hands isn't JavaScript's default ```js async function onCommand(channel, arguments) { // Assuming the command is not empty and - // there is always the first argument. + // there is always the first argument. let commandName = arguments[0]; - switch (commandName) { - // ... - case "getUser": - if (arguments.length < 2) - throw "Usage: /getUser "; - // It is guaranteed now that "arguments" has at least 2 elements - // and thus there is an index 1. - let username = arguments[1]; - let user = await botClient.fetchUser(username); - channel.send(JSON.stringify(user); - break; - // ... - } + switch (commandName) { + // ... + case "getUser": + if (arguments.length < 2) + throw "Usage: /getUser "; + // It is guaranteed now that "arguments" has at least 2 elements + // and thus there is an index 1. + let username = arguments[1]; + let user = await botClient.fetchUser(username); + channel.send(JSON.stringify(user); + break; + // ... + } } ``` @@ -170,8 +170,8 @@ sure that situation is handled properly. async function getUserID(username) { // Assuming "username" is guaranteed to be a string. let user = await botClient.fetchUser(username); - if (user == null) throw "There is no user with that name."; - // It is guaranteed now that "user" isn't null. + if (user == null) throw "There is no user with that name."; + // It is guaranteed now that "user" isn't null. return user.id; } ``` From f782589856b2b4eedf1b79b08c3eb5e1db494456 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=AA=20Duy=20Quang?= Date: Mon, 18 Jan 2021 21:29:46 +0700 Subject: [PATCH 4/5] Added a cause and fix for the cannot read property error. --- .../javascript/cannot-read-property.md | 46 +++++++++++++++++-- 1 file changed, 43 insertions(+), 3 deletions(-) diff --git a/src/content/resources/language/javascript/cannot-read-property.md b/src/content/resources/language/javascript/cannot-read-property.md index 604b9e8..dddd1d3 100644 --- a/src/content/resources/language/javascript/cannot-read-property.md +++ b/src/content/resources/language/javascript/cannot-read-property.md @@ -11,7 +11,7 @@ When running JavaScript code, a very common error that occurs is: console.log(someRandomThing.abc) ^ -TypeError: Cannot read property "abc" of undefined +TypeError: Cannot read property "abc" of undefined. ``` This is a very basic error, yet people who are new to JavaScript (and maybe @@ -33,7 +33,7 @@ $ node undefined > console.log(someRandomThing.abc); // ---- Owner ----|Property -Uncaught TypeError: Cannot read property 'abc' of undefined +Uncaught TypeError: Cannot read property "abc" of undefined. ``` The most important thing to note here is it's the "_owner_" that is being @@ -124,7 +124,23 @@ undefined // and remains undefined. undefined > console.log(payload.message) -Uncaught TypeError: Cannot read property 'message' of undefined +Uncaught TypeError: Cannot read property "message" of undefined. +``` + +#### `undefined` from missing parameters + +If a function accepts a number of parameters, but the calling code passes fewer +than that, the missing parameters are defaulted to `undefined`. + +```js +> function getValue(object) { +... return object.value; +... } +undefined +> getValue({ value: 15 }) +15 +> getValue() // ! No value is given to "object", defaults to undefined. +Uncaught TypeError: Cannot read property "value" of undefined. ``` ## Fixing @@ -191,3 +207,27 @@ else // In either case, "payload" is guaranteed to be assigned an actual value. botClient.sendMessage(serverJoiner, payload.message); ``` + +#### Make sure a function is called correctly + +When calling a function, make sure enough parameters are passed as required, or +provide default values for function arguments, if applicable. + +```js +function sendEmbed(content, options = { color: "#888", dismissable: false }) { + let embed = botClient.createEmbed(); + embed.setContent(content); + embed.setColor(options.color); + embed.setDismissable(options.dismissable); + botClient.sendEmbed(embed); +} + +sendEmbed( + "The programmer's hangout: https://theprogrammershangout.com", + { color: "#763989", dismissable: true } +); + +sendEmbed("Example site: https://example.com"); +// No value is passed to "options" by the caller, +// defaults to the value specified in the function declaration. +``` From 46e8651b311ff868937fbe93937befdabddd2033 Mon Sep 17 00:00:00 2001 From: Jean-Philippe Sirois Date: Thu, 25 Feb 2021 04:24:10 -0500 Subject: [PATCH 5/5] style: auto-format --- .../javascript/cannot-read-property.md | 66 +++++++++---------- 1 file changed, 32 insertions(+), 34 deletions(-) diff --git a/src/content/resources/language/javascript/cannot-read-property.md b/src/content/resources/language/javascript/cannot-read-property.md index dddd1d3..1e975ed 100644 --- a/src/content/resources/language/javascript/cannot-read-property.md +++ b/src/content/resources/language/javascript/cannot-read-property.md @@ -84,22 +84,22 @@ read property" error might arise. ```html - -

Welcome to The programmer's hangout.

-

- This is the place for programmers of any skill level to, well, hangout - with other fellow programmers. Whether you have just written 5 lines of - code or been a code nerd for 15 years, you are always welcome! -

- - + +

Welcome to The programmer's hangout.

+

+ This is the place for programmers of any skill level to, well, hangout + with other fellow programmers. Whether you have just written 5 lines of + code or been a code nerd for 15 years, you are always welcome! +

+ + ``` @@ -184,11 +184,11 @@ sure that situation is handled properly. ```js async function getUserID(username) { - // Assuming "username" is guaranteed to be a string. - let user = await botClient.fetchUser(username); - if (user == null) throw "There is no user with that name."; - // It is guaranteed now that "user" isn't null. - return user.id; + // Assuming "username" is guaranteed to be a string. + let user = await botClient.fetchUser(username); + if (user == null) throw "There is no user with that name."; + // It is guaranteed now that "user" isn't null. + return user.id; } ``` @@ -200,10 +200,8 @@ ultimately receive a value, the error won't be able to occur. ```js let payload; let rolledValue = Math.random(); -if (rolledValue > 0.5) - payload = { id: 169323, message: "Welcome to TPH." }; -else - payload = { id: 173205, message: "TPH has been waiting for you." }; +if (rolledValue > 0.5) payload = { id: 169323, message: "Welcome to TPH." }; +else payload = { id: 173205, message: "TPH has been waiting for you." }; // In either case, "payload" is guaranteed to be assigned an actual value. botClient.sendMessage(serverJoiner, payload.message); ``` @@ -215,17 +213,17 @@ provide default values for function arguments, if applicable. ```js function sendEmbed(content, options = { color: "#888", dismissable: false }) { - let embed = botClient.createEmbed(); - embed.setContent(content); - embed.setColor(options.color); - embed.setDismissable(options.dismissable); - botClient.sendEmbed(embed); + let embed = botClient.createEmbed(); + embed.setContent(content); + embed.setColor(options.color); + embed.setDismissable(options.dismissable); + botClient.sendEmbed(embed); } -sendEmbed( - "The programmer's hangout: https://theprogrammershangout.com", - { color: "#763989", dismissable: true } -); +sendEmbed("The programmer's hangout: https://theprogrammershangout.com", { + color: "#763989", + dismissable: true, +}); sendEmbed("Example site: https://example.com"); // No value is passed to "options" by the caller,