Lesson Description

The "Debugging with the Console" Lesson is part of the full, Getting Started with JavaScript, v3 course featured in this preview video. Here's what you'd learn in this lesson:

Kyle introduces advanced console debugging techniques to the students. He explains the different levels of logging available, such as errors, warnings, debug information, and info. He demonstrates how to use console.group to organize logs into collapsible groups, console.table to display data in a table format, and console.assert for conditional error logging.

Preview

Transcript from the "Debugging with the Console" Lesson

[00:00:00]
>> WebDevSimplified: And moving on, before we start diving into the rest of the dev tools such as that Sources panel, I want to talk about some advanced console debugging that you can do. We've already looked at console.log for just printing out basic information, but this console object has tons of different methods on it. For example, we actually have four different levels of logging we can use. We've already seen errors that was red things that show up inside of our editor or inside of our console.

[00:00:21]
Those are errors that show up, and we can make our own by just rendering console.error. But we can also render out warnings which show up in yellow using console.warn. We can print out debug information, which is like really low-level information that doesn't even show up by default by using console.debug, and console.info is essentially the exact same as console.log, but it says info level of information.

[00:00:42]
We just copy over what that looks like, and I'm going to bring my tools off to the side. We print that down, you can see that I'm getting three different things being logged out currently. I'll just refresh that real quick. You can see "application started successfully." That's in that normal default white color because console.info is the same as console.log, essentially. Warnings by using console.warn is going to show up in that yellow color and it's going to have this little icon next to it, and I can expand it to view the full stack trace.

[00:01:08]
In our case, we don't have any functions, so it just shows me where it's being called at. Error is the same thing, but it shows up as red and again gives me that full stack trace. And even though this debug one doesn't even show up by default, and that's because inside of most browsers this is hidden by default. Where you see it says default levels, if you click on this, you can change this to say verbose as well, and now that shows you anything inside console.debug.

[00:01:30]
So this console.debug is great for information that you maybe want to show in some cases, but for the most part you want it to be hidden by default. That's why usually I keep this to the default setting that hides those more debug verbose logging sections. Now you can also filter, like I said with that section, and you can add the verbose section or you can even filter it down. For example, if you only want to see errors, you can check off everything that's not an error, and now it'll only show you errors, which is really useful.

[00:01:55]
Let's just bring that back to that default section though, because that's generally what you're going to want it to be at. We can also group our console input. Again, I'll copy this over and dive into what the code is doing, but it's much easier to see visually what's going on. So you can see on the right-hand side, our logs are actually grouped. We can toggle them down and open to see different levels of grouping inside of our application.

[00:02:15]
And this is all handled using this group function. When you call console.group, you can give it a name if you want, and that'll show up as the name next to your little icon to expand and collapse. And then any logs that you put after that will be grouped inside of there, and you can nest your groups together. For example, we put a brand new group in here called "database connection," which now has its own set of grouping.

[00:02:35]
And to stop the groups from collapsing or from continuing further, you just use group.end. That ends your group completely and now essentially everything between group and group.end are in its very own collapsible group. Same thing here, we have another group.end and everything between those is in its very own collapsible group. This is great for more complex logs where you want to show information, but you don't want to clutter your log with all of it, so you can just have a group.

[00:02:57]
You can also use group.collapsed. This will just make it so by default when you refresh your page, the group is going to be collapsed, which means it's much easier if you have a lot of information. You can make sure it starts out collapsed, and if someone needs to see it, they can open it up and view what that particular information is going to be. Now rendering out information in a table format is also really useful.

[00:03:14]
For example, let's say that I have a bunch of different users and I want to render them out. So here, I'm just going to console.log my users before I reference this table so we can see the difference between these two. You can see here I have an array of different users with information, and when I console.log them out, you can see it's kind of hard to parse what everything is inside of this object over here.

[00:03:33]
I have to manually click through and open up a bunch of different things. This is where the table function comes in. Instead of console.log, I can use console.table, and now it puts it in this nice table format and it gives me all the different columns of everything that I can reference for my particular objects inside this array. And this is really only useful for when you have an array with objects inside of it.

[00:03:51]
You can also pass a second property here that's going to say the different properties that you want to have. So for example, if I want to have just the name and the age property, I could pass an array with those two properties and now you can see those are the only two things being printed out in my table, again useful for debugging arrays of objects. Now console assertions are really great for specific cases where it'll log out an error, but only if something is true.

[00:04:14]
Sometimes in your code, you may have something like this where it says if and then you put some type of statement, doesn't matter what it is, and then you do a console.error "we are here" or something along those lines, and you only want to log that error in specific cases. This is where console.assert comes in. By using console.assert just like this, we can pass it in our condition, so we'll just say like age is greater than 20, for example, and we'll create that age variable.

[00:04:39]
And we'll make it 21, so it is greater than 20, and then we can put whatever our error message is. "Error," we'll just put it like that. So now when I save, you'll notice by default nothing's being logged, and that's because if this first statement evaluates to true, it doesn't log anything at all. But if this statement evaluates to false, so for example our age is 19, it's actually going to log out whatever this error is.

[00:04:59]
So it'll say "assertion failed," followed by whatever text I put here, so I can change this text. You can see it updates that section, and it gives me a full stack trace of where everything happened. This is a great way to only log things if you actually have something that you want to log, so you don't need to wrap it in an if, you can just do it all inline like this. Now the main place that I find console.assert really useful is if, for example, you know that this user variable somewhere is becoming null but you're not sure where, you can put a bunch of console.asserts with different values afterwards and then you know, for example, if it logs out 2 and 4 in your log, you know that somewhere in console.assert before or after this, the value is set to null, and here you also know that the user is null whenever we get to this particular point, so it can help you narrow down where your particular bug in your code is.

[00:05:46]
Now you can also time how long different things take. For example, you can use console.time to start a timer and console.timeEnd to end a timer, and that'll evaluate how long that particular thing took. So here we just put console.time, give it a name that starts a timer. We run some code, in our case we're just running a bunch of fake code. And then finally we're going to end what that timer is. So if I give this a save, you can see to run through this loop whatever it is like 10,000, 10 million times, it took 1.5 milliseconds, and if code took longer or shorter, it'll tell me that exact value out here.

[00:06:14]
This is really great for when you have performance problems in your code. You can figure out why those performance problems are occurring. You can also use the console for counting. If you use this console.count method and pass it in a string, which is the label for your counter, it'll count up how many times you essentially call that particular console.count method. So here we're calling "process item" and we're saying here, OK, "items processed" 1, 2, 3, essentially that's our counter, so it's just counting up every single time we call this function.

[00:06:43]
And we can also reset our counter by passing it in the same name, and it'll reset us back to the one value, so the next time we call this, the value will be 1. I don't use this super often, but if you want to try to figure out how many times you're calling something, the console.count method can help. Finally, we can just get a stack trace. You may remember in some of our code, if we wanted to get a stack trace, we could do like a console.error, pass it in some message, and you can see it gives us a stack trace of all the functions we call to get to this particular point.

[00:07:13]
Well, we can actually just get a stack trace by calling console.trace, and it'll give you that stack trace. So if we copy this code, paste this down, you can see it gives me that full stack trace as well as whatever message I put right here. So if you just want to see how did I get to this particular point, console.trace is a great way for that. Now, this is probably the most important part of this entire page, and that is the biggest pitfall with console.log, and that is that it always shows you the most up-to-date live version.

[00:07:42]
Let's take a look at this particular code. We have a user with a name of Alice and an age of 25. I then log out that user and then finally I update their age to 26. When I save, you can see it says name Alice, age 25. That seems to make a lot of sense. If I expand this though, the age is now set to 26 and the name is still Alice. That's because whenever you expand something inside of your console, it's going to render whatever the most up-to-date version of that particular value is.

[00:08:07]
Generally, this is probably not what you want though, because I want to know what did this user look like exactly when I logged it. I don't care what it looks like now in the future. I want to know what it looked like at this point, which is why if we come over here, you can see the fix to this is by using a function called structuredClone. So we can come in here, type out structuredClone, which is a function built into JavaScript, and all that does is completely copy this user object and give me a brand new user object that's entirely different.

[00:08:33]
So now when I expand this, you notice it keeps all the same values I had originally when I logged out my user. So if you're ever wondering why something when you log out is different than you expect it to be, it's probably because it's getting the most up-to-date value, and you probably want this structuredClone to fix that problem for you, and this works with arrays or it works with objects, either one.

Learn Straight from the Experts Who Shape the Modern Web

  • 250+
    In-depth Courses
  • Industry Leading Experts
  • 24
    Learning Paths
  • Live Interactive Workshops
Get Unlimited Access Now