Beyond console.log - you can do more!

Tobias
#debugging  #javascript 

Most web developers and I am sure every javascript developer knows how to print messages to the console, using console.log in the browser. It is the easiest way to get information about the code and helps the developers, when they are debugging a problem and don’t want to use the debugger because they don’t want to dive too deep into a framework like Vue.js or have any other reason. But there is more than the console.log command and in this article we will look at these other options.

console.log()

Let’s start with the basics. Everyone knows that you can use the log function to print out strings, objects and arrays. Here is a short example for the output (Foo is a string, user an object and books an array):

console.log('Foo', user, books);

Permission

But you can even do more with the log function. First there is the possibility to return a formatted string. Either with a simple string concatenation or with some kind of sprintf function as known from PHP.

console.log('I like the ' + user.job + ' ' + user.short + ' very much.');
console.log('I like the %s %s very much.', user.job, user.short);

Permission

If you choose %o instead of %s, you can use a object as placeholder. And if you want, you can even use css with the %c placeholder. Here is a short example, but I’ve never needed this case before.😅

console.log('I am a placeholder for %cCSS', 'color: orange; background-color: black; padding: 2px 5px; border-radius: 2px');

Permission

console.dir()

For the most part, the dir() function is very much like log(), though it looks a little bit different. Things get more interesting when you select an element and look at the result. With the log() output, we get the children of the DOM-Element we have selected. With dir() we get an interactive listing of the properties about the HTML-Element, which may be useful from time to time. Permission

Information levels

console.info, console.warn and console.eror are the three information levels the console contains. You can use them to weight the information in an application differently.

console.info('Hello World');
console.warn('Hello World');
console.error('Hello World');

Permission

console.group()

With the group() function it becomes really simple to properly organize related data and represent each group with a definitive label. The label always remains optional. To close the group, there is the function groupEnd().

console.group('Levels');
console.group(); // No label
console.info('Hello, I am an info');
console.group('Warning');
console.warn('Hello, I am a warning');
console.group('Error');
console.error('And I am an error');
console.groupEnd();
console.groupEnd();
console.groupEnd();
console.groupEnd();
console.log('All groups closed');

Permission

We don’t have to pass the name to the groupEnd() function, because it will always close the recently created group. Groups created by group() are initially opened. In case you want the group to appear collapsed just use groupCollapsed().

console.clear()

Sometimes there is just way too much information in the console and also a lot of bullshit from extensions or old bugs that don’t interest us anymore. To get a usable console again, you can empty the console with the clear command.

console.clear();

Be aware if the preserve log option is active, this command does not work.

console.table()

With the the table() function you can display tabular data in a way that’s much neater than just dumping out the object.

console.log(data);
console.table(data);

Permission

console.assert()

Console.assert is my personal favourite. This function is used to run simple assertion. It needs two required arguments, the first one is is the expression which should be truthy or falsy. The second argument is the message you want to print. But the message is only printed, if the expressions is falsy. Using this function, you don’t need to write a if-condition, to show the message. Console.assert saves me so much time, it’s easy to use, but it’s damn useful to hunt nasty bugs. I recommend to try out this function, unless you already use it of course.

console.assert(5 > 10, 'This is bullshit, so we get a message.');
console.assert(10 > 5, 'This is correct, so we do not see the message.');

Permission

console.count()

This function is used to set a counter of how many times a particular string gets logged in the console. The first argument is an optional label, which can be used to have a named counter. If no label is given, the label is the given string.

console.count('foo', 'some-string');
console.count('no-label');
console.count('foo', 'some-string');
console.count('foo', 'some-string');
console.countReset('foo');
console.count('foo', 'some-string');

Permission Consider, this this function only works with strings and can currently not distinguish between different objects. If you want to reset the the counter use the countReset() function.

console.time()

The time() function starts a timer that can be used to compute the duration of an operation. This timer can be stopped with timeEnd(), additionally timeEnd() prints the total time in milliseconds to the console. Timers can be identified by a given label. If no label is given the timeEnd will stop the most recent time function. You can use this function if you need to check the performance of a piece of code. This method is much more accurate than to write date.now at the start and end to the console and then calculate the difference.

console.time();
let sum = 0;
for (let i = 0; i < 1000; i += 1) {
    sum += i;
}
console.timeEnd();

// Output
default: 0.0283203125ms

console.profile()

I recently discovered this feature for myself when I started working on performance optimizations for one of my applications. With the profile() function you can record a performance profile of the CPU and memory usage where it is called. You can give the profile an optional name and find the recording in the JavaScript Profiler tab. If you don’t see the tab, you have to go to more tools in the settings and select the JavaScript Profiler. To end the recoding use the profileEnd() function. I am sorry, I couldn’t come up with a simple and realy usefull example, but I hope you get the idea behind this function.

console.profile('simple example');
let sum = 0;
for (let i = 0; i < 100000; i += 1) {
    sum += i;
}
console.profileEnd('simple example');

// Output
Profile 'simple example' started.
Profile 'simple example' finished.

Permission

console.trace()

Sometimes, while debugging a complex problem we get stuck in the dead end of detecting the problem because a function is called too many times and we don’t know where the issue comes from. Imagine you have a validation service that is called in different components or even by other services. And one of these calls results in an error, but the default error message only tells you that the error is in the service. This message is not necessarily helpful. But now we want to find out which consumer produces this error. This is exactly the time when you can use the trace() function.

function isGreaterThan(a, b) {
    console.trace();
    return a > b;
}

function callGreater() {
    this.isGreaterThan(4, 2);
}

function traceExample() {
    this.isGreaterThan(10, 5);
    this.callGreater();
    this.isGreaterThan(undefined, 3);
}

traceExample();

Permission

console.memory

If you have an even more sneaky problem, for example you have a tricky lack of memory you could check your memory heap size status. Therefor, you use the meomory property of the console, yeah - this is just a porperty and not a function.

console.memory

//Output
MemoryInfo {
    totalJSHeapSize: 10000000,
    usedJSHeapSize: 10000000,
    jsHeapSizeLimit: 3760000000,
}

Wrapping it up

The console is a pretty powerful tool for a web developer. It offers so much more than just the log function, so try to include one of these other functions in your debugging process, it can really save a lot of time and even nerves at the end of the day.

Sources


Tobias

Tobias is Lead Web Developer at karriere.at and programmer with heart and soul, he loves to bury himself in complex problems and to master them with creative solutions. Frontend, Backend doesn’t matter, he enjoys every task.
If there is no improvement for a web application on the agenda, he likes to learn more about artificial intelligence and machine learning.


We're a team of makers, thinkers, organisers and digital explorers and we're always on the lookout for talented people.

Are you a good fit?