DEV Community

Cover image for Oops, I did it again: A guide to debugging common JavaScript errors
Ali Spittel
Ali Spittel

Posted on

Oops, I did it again: A guide to debugging common JavaScript errors

Writing JavaScript code can sometimes make us feel like running, hiding, or just being scared. But, with some debugging tips we can get in the zone and then dance until the world ends!

TypeError: Cannot read property "lucky" of undefined

let girl = {
    name: "Lucky",
    location: "Hollywood",
    profession: "star",
    thingsMissingInHerLife: true,
    lovely: true,
    cry: function() {
        return "cry, cry, cries in her lonely heart"
    }
}

console.log(girl.named.lucky)
Enter fullscreen mode Exit fullscreen mode

This code throws the error "Uncaught TypeError: Cannot read property 'lucky' of undefined". In our girl object, we don't have the property named, though we do have name. Since girl.named is undefined, we can't access a property on something that doesn't exist. So, as is true for the girl named Lucky, something's missing from our life (or object). We would want to change girl.named.lucky to girl.name, and we'd get "Lucky" in return!

A property is a value in a JavaScript object. You can read more about objects here.

Steps to debug TypeErrors

TypeErrors are caused by trying to perform an operation on something that doesn't have a data type that matches up with said operation. So, trying to run .bold() on a number, retrieve an attribute on undefined, or trying to run something like a function that's not a function (for example girl() would throw an error -- girl is an object, not a function). On the last two, we'd get "Uncaught TypeError: yourVariable.bold is not a function" and "girl is not a function".

In order to debug these errors, you need to check your variables -- what are they? What is girl? What is girl.named? Is it what it's supposed to be? You can check this by looking at your code, console.log-ing your variables, using a debugger statement, or just typing the variable into the console and seeing what it is! Make sure you can perform the action on the data type of the variable. If not, cast the data type of the variable, add a conditional or try/catch to only run that action sometimes, or run the action on something else!

Stack overflow

According to the songwriters for "Baby One More Time", the "hit" in "Hit me baby, one more time" refers to a call, so Britney wants her ex-partner to call her one more time. Which will probably lead to more and more calls in the future. This mirrors recursion -- which, if the call stack size is overflowed, will cause errors.

These change by browser, but can look like:

Error: Out of stack space (Edge)
InternalError: too much recursion (Firefox)
RangeError: Maximum call stack size exceeded (Chrome)
Enter fullscreen mode Exit fullscreen mode

This can be caused by not having a recursion base case, or having a base case that never fires.

function oneMoreTime(stillBelieve=true, loneliness=0) {
    if (!stillBelieve && loneliness < 0) return
    loneliness++
    return oneMoreTime(stillBelieve, loneliness)
}
Enter fullscreen mode Exit fullscreen mode

In the above function, stillBelieve never becomes false and loneliness keeps increasing, so we keep recursively calling oneMoreTime without ever exiting the function.

If we instead make it so that Britney relies on her friends, instead decreasing her loneliness, and she stops believing in the relationship, she'll stop wanting her ex-partner to call.

function oneMoreTime(stillBelieve=true, loneliness=0) {
    if (!stillBelieve && loneliness < 0) return
    loneliness--
    stillBelieve = false
    return oneMoreTime(stillBelieve, loneliness)
}
Enter fullscreen mode Exit fullscreen mode

There's a similar issue with infinite loops, though instead of getting an error message, our page usually just freezes. This happens when we have an un-terminated while loop.

let worldEnded = false

while (worldEnded !== true) {
  console.log("Keep on dancin' till the world ends")
}
Enter fullscreen mode Exit fullscreen mode

We can fix this in a similar way!

let worldEnded = false

while (worldEnded !== true) {
  console.log("Keep on dancin' till the world ends")
  worldEnded = true
}
Enter fullscreen mode Exit fullscreen mode

Debugging infinite loops and unterminated recursion

First, if you're in an infinite loop, quit the tab if you're in Chrome or Edge, and quit the browser window in FireFox. Then, do a check on your code: is there something that's glaringly creating the infinite loop/recursion? If not, I would add a debugger statement to the loop or function and make sure the variables are what they should be in the first few iterations -- you'll probably notice a pattern of something being off. In the above example, I would put a debugger in the first line of the function or loop. Then, I'd go to the debugging tab in Chrome, look at the variables in Scope Then, I'd click the "next" button to see what they are after an iteration or two. Usually that will get us to the solution!

This is a great guide to debugging with Chrome's DevTools, and here's one for FireFox.

Uncaught SyntaxError: Unexpected identifier

Potentially the most common category of errors in JavaScript is SyntaxError's -- these mean that we aren't following the syntax rules of JavaScript. To follow the sentiment of Britney in "Everytime", JavaScript is saying "I guess I need you baby" to our missing parenthesis, brackets, and quotation marks.

I would make sure you have a good text editor theme or extensions installed if you struggle with these types of errors -- Bracket Pair Colorizer helps color code braces and brackets, and Prettier or another linter can help catch these errors fast. Also, make sure to properly indent your code and keep codeblocks short and as un-nested as possible. This will make debugging any issues easier!


Now, with your new debugging skills, you can feel a little stronger than yesterday at JavaScript. If you are thinking Gimme More pop culture code references, here's thank u next: an introduction to linked lists.

Top comments (20)

Collapse
 
emmabostian profile image
Emma Bostian ✨

I literally don't have words

Collapse
 
zeddotes profile image
zeddotes

Cannot read property 'words' of undefined.

Collapse
 
kevinhq profile image
kevin

lol

Collapse
 
jochemstoel profile image
Jochem Stoel
function oneMoreTime(stillBelieve=true, loneliness=0) {
    if (!stillBelieve && loneliness < 0) return
    loneliness++
    return oneMoreTime(stillBelieve, loneliness)
}

This is poetry.

Collapse
 
gypsydave5 profile image
David Wickes

First, if you're in an infinite loop, quit the tab if you're in Chrome or Edge, and quit the browser window in FireFox.

FireFox is a lot friendlier than this - you don't need to close the whole browser and you get a nice, friendly message:

too much recursion indeed!

Collapse
 
andy profile image
Andy Zhao (he/him)

Big fan of the Bracket Pair Colorizer extension! Before, I didn't know that something wasn't right, and it definitely gives you a sign!

Collapse
 
daveskull81 profile image
dAVE Inden

I didn’t know about this extension. I’m totally going to try it out. It seems like it would save me a bunch of time.

Collapse
 
laurieontech profile image
Laurie

So now the question is which of the referenced songs am I listening to first...

I've always been partial to Everytime :)

Collapse
 
gabrielecimato profile image
Gabriele Cimato

Ahah brilliant!

Collapse
 
annarankin profile image
Anna Rankin

Nice one Ali! We recently started using Prettier on one of our projects and I love it - it catches silly mistakes and quells syntax debates 🤘 thanks as always!

Collapse
 
noor_codes profile image
Noorullah Ahmadzai

const Ali = {
Name: 'Ali',
LovesBritney: true,
ShoutOut: function(){
console.log('Ali is awesome');
}

Ali.ShoutOut();

😅

Collapse
 
noor_codes profile image
Noorullah Ahmadzai

Loved the way you explained the full stack issue, the rest I had a basic info about!
Still learnt something new 😃

Collapse
 
tuxrafa profile image
Rafael Oliveira

It's wonderful!!!
Sometimes these errors makes anyone Crazy, but Everytime I got these errors, I'll remember this text.