Code With Wolf


Type Error vs Reference Error in JavaScript

Type Error Vs Reference Error in JavaScript

Here are two errors that I see in my browser console all the time when working with JavaScript.

There are tons of different JavaScript errors and they can be found in the Mozilla docs, here.

For this post, I wanted to specifically get into the difference between TypeError vs ReferenceError.


A simple example of both can be see here:

type-error-reference-error-console

Let's see what is really going on...



ReferenceError

When you create a variable, all you are doing is creating a reference with a value. var a = "I'm a string" tells the JS compiler that any time it sees the variable a, it is seeing a string with a value of "I'm a string".

Without that variable declaration, JS has no idea what to do when it comes across a because there is no reference, so it throws an error.

var a = "I'm a string";

console.log(a) // I'm a string
console.log(b) // Uncaught ReferenceError: b is not defined.

In the above example, JS knows what to do when it comes across a. It hasn't the slightest idea what to do when it comes across b so it throws a tissy fit and a ReferenceError.


TypeError

A TypeError is not too far off from a ReferenceError. The JS compiler is telling you that however you are attempting to use your variable is not how it is intended.

Here is one example:

var a = "I am a string";

console.log(a) // I am a string

console.log(a()) // Uncaught TypeError: a is not a function

The error message is clean and telling you exactly what is wrong in this very simple example. You are trying to invoke a as though it is a function, but yet, it is a lowly string.

What you are looking for is:

var a = function(){
    return "I am a string"
}

console.log(a()) // I am a string

Cannot read property of undefined

This is a common TypeError I see so I wanted to address it because it is very preventable. I will often see it when missing a null check on async fetches. I might call an API and be expecting something like response.data.someProperty.anotherProperty and before I check to make sure that response, response.data, and response.data.someProperty are truthy, I try accessing response.data.someProperty.anotherProperty.

Here is an incorrect example:

    function async doSomethingAsync(url){
        let response = await goFetchSomeData(url);
        let dataToLogToConsole = response.data.someProperty.anotherProperty;
        console.log(dataToLogToConsole);
    }
    // Uncaught TypeError: cannot read property 'someProperty' of `undefined`.

In the above example, we are trying to access someProperty from the response.data property, but that seems to be of type undefined.

What we should be doing is checking that all of the parent properties exist and are truthy before we try to access their nested properties.

The example above would throw a TypeError because you are trying to access data from a property that is of type undefined. The JS compiler sees you as trying to do the same thing as trying to invoke a string in the previous example, your code is not using the type of response.data or a as intended.

Here is a more correct example:

    function async doSomethingAsync(url){
        let response = await goFetchSomeData(url);

        if(response && response.data && response.data.someProperty){
            let dataToLogToConsole = response.data.someProperty.anotherProperty;
            console.log(dataToLogToConsole);
        }else{
            console.error('The data was not available');
        }
    }

This example will either log the nested data, or will log the error to the console. It will not throw a type error.

Tldr;

JS Errors are intimidating when you see them in the console with their alerting red letters. Often I freak out a bit and my heart rate rises, no matter how often I see these errors.

When actually looking at what the error is telling you and then debugging my code, the JS errors are there to help and not scare you, though they can definitely be frustrating at times.

In short, a ReferenceError is just saying that the variable you are using has no reference. A TypeError is telling you that you are not using the variable's type correctly. It's incredibly simple if you think about it.



© 2022 Code With Wolf