DEV Community

Cover image for JavaScript: Avoid Run-Time Console Errors
Ankit Tanna
Ankit Tanna

Posted on

JavaScript: Avoid Run-Time Console Errors

I HATE RUN-TIME CONSOLE ERRORS

Here, I have said it in big bold capital letters. Usually they arise because you try to access a property of undefined or null.

You must have been aware of this dreadful image:
Web console run-time error image

This happens usually when we try to do something like this:

function printPersonDetails(person) {
   console.log(person.age);
}

printPersonDetails(undefined);
Enter fullscreen mode Exit fullscreen mode

As soon as you pass person as undefined the clock of the doomsday starts ticking and at any moment when this function is triggered, you shall see the run-time error.

You might argue that you could write unit tests but since JavaScript provides all the fallback mechanisms in place then why wait for unit tests to be written.

Option 1 - Use default values for function parameters

This is the least a developer should do.

Before

function add(a, b, c) {
   return a + b + c;
}

add(1, undefined, 2); // Run-time error
Enter fullscreen mode Exit fullscreen mode

After

function add(a=0, b=0, c=0) {
   return a + b + c;
}

add(1, undefined, 2); // Run-time error
Enter fullscreen mode Exit fullscreen mode

Providing default values to parameters is a good practice.

Option 2 - Nullish coalescing operator (??)

This (??) new symbol is a life saver. This is a logical operator that returns RHS operator if LHS is null/undefined.
RHS/LHS - right/left hand side (duh!)

I 💗 this feature!

function add(a, b, c) {
 const valOfA = a ?? 0;
 const valOfB = b ?? 0;
 const valOfC = c ?? 0;
 return a + b + c;
}

add(null, undefined, null); // Run-time error
Enter fullscreen mode Exit fullscreen mode

Option 3 - Logical Nullish assignment operator (??=)

This (??=) new symbol is another life saver. The logical nullish assignment (x ??= y) operator only assigns if x is nullish (null or undefined).

I 💗 this feature!

function printPersonDetails(person) {
   person.age ??= 0;
   console.log(person?.age); // 0 and no run-time error
}

printPersonDetails({age: undefined});
Enter fullscreen mode Exit fullscreen mode

Option 4 - Destructuring and Rest defaults

This option is also pretty handy but can take some time to wrap your head around.

Before

var tmp = getSomeRecords();

var first = tmp[0];
var second = tmp[1];

var firstName = first.name;
var firstEmail = first.email !== undefined ? first.email : "nobody@none.tld";

var secondName = second.name;
var secondEmail =
  second.email !== undefined ? second.email : "nobody@none.tld";

function getSomeRecords() {
    return [
      {
        name: "a",
        email: "a@gmail.com",
      },
      {
        name: "b",
        email: "b@gmail.com",
      },
    ];
}
Enter fullscreen mode Exit fullscreen mode

After

var [
  {
    name: firstName,
    email: firstEmail = "nobody@none.com"
  },
  {
    name: secondName,
    email: secondEmail = "nobody@none.com"
  }
] = getSomeRecords();

function getSomeRecords() {
  return [
    {
      name: "a"
    },
    {
      name: "b",
      email: "b@gmail.com",
    },
  ];
}
Enter fullscreen mode Exit fullscreen mode

The same rest parameter concept can be applicable to function parameters as well.

Before

function printPersonDetails(person) {
   console.log(person.age);
   console.log(person.name);
}

printPersonDetails(undefined); // 💥 💥 Blast!!!
Enter fullscreen mode Exit fullscreen mode

After

function printPersonDetails({
   age: age = 0,
   name: name = 'john doe'
}) {
   console.log(age);
   console.log(name);
}

printPersonDetails(undefined); // Works

// OR if you are lazy to repeat properties
function printPersonDetails({
   age = 0,
   name = 'john doe'
}) {
   console.log(age);
   console.log(name);
}

printPersonDetails(undefined); // Works
Enter fullscreen mode Exit fullscreen mode

The above technique can also be useful if you have more than 3 parameters in your function and you don't like remembering the sequence of them (I don't). This feature is known as named-parameters.

Option 5 - Use Elvis(?) operator

I hate this option but I will still list it.

function printPersonDetails(person) {
   console.log(person?.age); // undefined and no run-time error
}

printPersonDetails(undefined);
Enter fullscreen mode Exit fullscreen mode

But what if person is not undefined and you tried to access a property inside age but age turns out to be undefined/null?

Option 5.1 Use Elvis(?) operator AND Non-Null Assertions (TypeScript 3.9 onwards only)

function printPersonDetails(person) {
   console.log(person?.age!.unit); // undefined and no run-time error
// OR
console.log((person?.age).unit); // undefined and no run-time error
}

printPersonDetails({ age: undefined });
Enter fullscreen mode Exit fullscreen mode

The (...) or ! provide the non-null assertions

These techniques are the ones that needs to be followed to avoid embarrassing production run-time errors on your console.

I have a small YouTube channel named EverydayJavaScript. Please do subscribe to the channel if you liked this post.

Happy error-free coding!

Discussion (1)