One place for hosting & domains

      How To Use console in Node.js


      Introduction

      In this article, we’ll learn how to use most methods available in the Node.js console class more effectively.

      Prerequisites

      This tutorial was verified with Chrome browser version 70.0.3538.77 and Node.js version 8.11.3.

      Using console.log, console.info, and console.debug

      The console.log method prints to standard out, whether this is the terminal or browser console.
      It outputs strings by default but can be used in conjunction with template strings to modify what it returns.

      console.log(string, substitution)
      

      console.info and console.debug methods are identical to console.log in their operation.

      You can use console.debug in the Firefox browser console by default but to use it in Chrome, you’ll have to set the log level to Verbose by toggling it on in the All levels menu.

      Screenshot depicting the developer tools with All levels menu selected and Verbose toggled on.

      The arguments in the template string are passed to util.format which then processes the arguments by replacing each substitution token with the respective converted value.

      The supported substitution tokens are:

      %s

      const msg = `Using the console class`;
      console.log('%s', msg);
      console.log(msg);
      

      This code would output the following:

      Output

      Using the console class Using the console class

      %s is the default substitution pattern.

      %d, %f, %i, %o

      const circle = (radius = 1) => {
        const profile = {};
        const pi = 22/7;
        profile.diameter = 2 * pi * radius;
        profile.circumference = pi * radius * 2;
        profile.area = pi * radius * 2;
        profile.volume = 4/3 * pi * radius^3;
      
        console.log('This circle has a radius of: %d cm', radius);
        console.log('This circle has a circumference of: %f cm', profile.diameter);
        console.log('This circle has an area of: %i cm^2', profile.area);
        console.log('The profile of this cirlce is: %o', profile);
        console.log('Diameter %d, Area: %f, Circumference %i', profile.diameter, profile.area, profile.circumference)
      }
      
      circle();
      

      This code would output the following:

      Output

      This circle has a radius of: 1 cm This circle has a circumference of: 6.285714285714286 cm This circle has an area of: 6 cm^2 The profile of this cirlce is: {diameter: 6.285714285714286, circumference: 6.285714285714286, area: 6.285714285714286, volume: 7} Diameter 6, Area: 6.285714285714286, Circumference 6
      • %d will be substituted by a digit (integer or float).
      • %f will be replaced by a float value.
      • %i will be replaced by an integer.
      • %o will be replaced by an Object.

      %o is especially handy because we don’t have to use JSON.stringify to expand our object because it shows all the object’s properties by default.

      Note that you can use as many token substitutions as you like. They’ll just be replaced in the same order as the arguments you pass.

      %c

      This substitution token applies CSS styles to the substituted text.

      console.log('LOG LEVEL: %c OK', 'color: green; font-weight: normal');
      console.log('LOG LEVEL: %c PRIORITY', 'color: blue; font-weight: medium');
      
      console.log('LOG LEVEL: %c WARN', 'color: red; font-weight: bold');
      console.log('ERROR HERE');
      

      This code would output the following:

      Screenshot of console output with OK in green, PRIORITY in blue, WARN in red.

      The text we pass to console.log after the %c substitution token is affected by the styles, but the text before is left as is without styling.

      Using console.table

      The first argument passed to it is the data to be returned in the form of a table. The second is an array of selected columns to be displayed.

      console.table(tabularData, [properties])
      

      This method will print the input passed to it formatted as a table then log the input object after the table representation.

      Arrays

      If an array is passed to it as data, each element in the array will be a row in the table.

      const books = ['The Silmarillion', 'The Hobbit', 'Unfinished Tales'];
      console.table(books);
      

      Screenshot of the books array displayed in a table format.

      With a simple array with a depth of 1, the first column in the table has the heading index. Under the index header in the first column are the array indexes and the items in the array are listed in the second column under the value header.

      This is what happens for a nested array:

      const authorsAndBooks = [['Tolkien', 'Lord of The Rings'],['Rutger', 'Utopia For Realists'], ['Sinek', 'Leaders Eat Last'], ['Eyal', 'Habit']];
      console.table(authorsAndBooks);
      

      Screenshot of the authorsAndBooks array displayed in a table format.

      Objects

      For objects with a depth of 1, the object keys will be listed under the index header and the values in the object under the second column header.

      const inventory = { apples: 200, mangoes: 50, avocados: 300, kiwis: 50 };
      console.table(inventory);
      

      Screenshot of the inventory object displayed in a table format.

      For nested objects:

      const forexConverter = { asia: { rupee: 1.39, renminbi: 14.59 , ringgit: 24.26 }, africa: { rand: 6.49, nakfa: 6.7 , kwanza:0.33 }, europe: { swissfranc: 101.60, gbp: 130, euro: 115.73 } };
      console.table(forexConverter);
      

      Screenshot of the forexConverter object displayed in a table format.

      Some more nested objects,

      const workoutLog = { Monday: { push: 'Incline Bench Press', pull: 'Deadlift'}, Wednesday: { push: 'Weighted Dips', pull: 'Barbell Rows'}};
      console.table(workoutLog);
      

      Screenshot of the workoutLog object displayed in a table format.

      Here, we specify that we only want to see data under the column push.

      console.table(workoutLog, 'push');
      

      Screenshot of the workoutLog object displayed in a table format but restricted to push exercises.

      To sort the data under a column, just click the column header.

      Pretty handy, eh?

      Try passing console.table an object with some values as arrays!

      Using console.dir

      The first argument passed to this function is the object to be logged while the second is an object containing options that will define how the resulting output is formatted or what properties in the object will be shown.

      What’s returned is an object formatted by node’s util.inspect function.

      Nested or child objects within the input object are expandable under disclosure triangles.

      console.dir(object, options);
      // where options = { showHidden: true ... }
      

      Let’s see this in action.

      const user = {
        details: {
          name: {
            firstName: 'Immanuel',
            lastName: 'Kant'
          },
          height: `1.83m"`,
          weight: '90kg',
          age: '80',
          occupation: 'Philosopher',
          nationality: 'German',
          books: [
            {
              name: 'Critique of Pure Reason',
              pub: '1781',
            },
            {
              name: 'Critique of Judgement',
              pub: '1790',
            },
            {
              name: 'Critique of Practical Reason',
              pub: '1788',
            },
            {
              name: 'Perpetual Peace',
              pub: '1795',
            },
          ],
          death: '1804'
        }
      }
      
      console.dir(user);
      

      Here it is in the Chrome console.

      Screenshot of the user object displayed in a hierarchical dir format.

      Using console.dirxml

      This function will render an interactive tree of the XML/HTML it is passed. It defaults to a Javascript object if it’s not possible to render the node tree.

      console.dirxml(object|nodeList);
      

      Much like console.dir, the rendered tree can be expanded through clicking disclosure triangles within which you can see child nodes.

      Its output is similar to that which we find under the Elements tab in the browser.

      This is how it looks when we pass in some HTML from a Wikipedia page.

      const toc = document.querySelector('#toc');
      console.dirxml(toc);
      

      Screenshot of a nested series of HTML elements from the table of contents of a Wikipedia page.

      Let’s pass in some HTML from a page on this website.

      console.dirxml(document)
      

      Screenshot of a nested series of HTML elements from the current website.

      This is how it looks when we pass in an object.

      Screenshot of the user object displayed in a hierarchical dirxml format.

      Try calling console.dir on some HTML and see what happens!

      Using console.assert

      The first argument passed to the function is a value to test as truthy. All other arguments passed are considered messages to be printed out if the value passed is not evaluated as truthy.

      The Node REPL will throw an error halting the execution of subsequent code.

      console.assert(value, [...messages])
      

      Here’s a basic example:

      • console.assert(false, 'Assertion failed');

      Output

      Assertion failed: Assertion failed

      Now, let’s have some fun. We’ll build a mini testing framework using console.assert

      const sum = (a = 0, b = 0) => Number(a) + Number(b);
      
      function test(functionName, actualFunctionResult, expected) {
        const actual = actualFunctionResult;
        const pass = actual === expected;
        console.assert(pass, `Assertion failed for ${functionName}`);
        return `Test passed ${actual} === ${expected}`;
      }
      
      console.log(test('sum', sum(1,1), 2)); // Test passed 2 === 2
      console.log(test('sum', sum(), 0));    // Test passed 0 === 0
      console.log(test('sum', sum, 2));      // Assertion failed for sum
      console.log(test('sum', sum(3,3), 4)); // Assertion failed for sum
      

      Run the above in your node REPL or browser console to see what happens.

      Using console.error and console.warn

      These two are essentially identical. They will both print whatever string is passed to them.

      However, console.warn prints out a triangle warn symbol before the message is passed:

      console.warn(string, substitution);
      

      Screenshot of console.warn(3).

      While console.error prints out a danger symbol before the message passed.

      console.error(string, substitution);
      

      Screenshot of console.error(2)

      Let’s note that string substitution can be applied in the same way as the console.log method.

      Here’s a mini logging function using console.error.

      const sum = (a = 0, b = 0) => Number(a) + Number(b);
      
      function otherTest(actualFunctionResult, expected) {
        if (actualFunctionResult !== expected) {
          console.error(new Error(`Test failed ${actualFunctionResult} !== ${expected}`));
        } else {
          // pass
        }
      }
      
      otherTest(sum(1,1), 3);
      

      Screenshot of console.error Test failed 2 !== 3.

      Using console.trace(label)

      This console method will print the string Trace: followed by the label passed to the function then the stack trace to the current position of the function.

      function getCapital(country) {
        const capitalMap = {
          belarus: 'minsk', australia: 'canberra', egypt: 'cairo', georgia: 'tblisi', latvia: 'riga', samoa: 'apia'
        };
        console.trace('Start trace here');
        return Object.keys(capitalMap).find(item => item === country) ? capitalMap[country] : undefined;
      }
      
      console.log(getCapital('belarus'));
      console.log(getCapital('accra'));
      

      Screenshot of stack trace for belarus displaying minsk and accra displaying undefined.

      Using console.count(label)

      Count will begin and increment a counter of name label.

      Let’s build a word counter to see how it works.

      const getOccurences = (word = 'foolish') => {
        const phrase = `Oh me! Oh life! of the questions of these recurring, Of the endless trains of the faithless, of cities fill’d with the foolish, Of myself forever reproaching myself, for who more foolish than I, and who more faithless?`;
      
        let count = 0;
        const wordsFromPhraseArray = phrase.replace(/[,.!?]/igm, '').split(' ');
        wordsFromPhraseArray.forEach((element, idx) => {
          if (element === word) {
            count ++;
            console.count(word);
          }
        });
        return count;
      }
      
      getOccurences();
      
      getOccurences('foolish');
      

      Here, we see that the word foolish was logged twice. Once for each appearance of the word in the phrase.

      [secondary_label]
      foolish: 1
      foolish: 2
      2
      

      We could use this as a handy method to see how many times a function was called or how many times a line in our code was executed.

      Using console.countReset(label)

      As the name suggests, this resets a counter having a label set by the console.count method.

      const getOccurences = (word = 'foolish') => {
        const phrase = `Oh me! Oh life! of the questions of these recurring, Of the endless trains of the faithless, of cities fill’d with the foolish, Of myself forever reproaching myself, for who more foolish than I, and who more faithless?`;
      
        let count = 0;
        const wordsFromPhraseArray = phrase.replace(/[,.!?]/igm, '').split(' ');
        wordsFromPhraseArray.forEach((element, idx) => {
          if (element === word) {
            count ++;
            console.count(word);
            console.countReset(word);
          }
        });
        return count;
      }
      
      getOccurences();
      
      getOccurences('foolish');
      
      [secondary_label]
      foolish: 1
      foolish: 1
      2
      

      We can see that our getOccurences function returns 2 because there are indeed two occurences of the word foolish in the phrase but since our counter is reset at every match, it logs foolish: 1 twice.

      Using console.time(label) and console.timeEnd(label)

      The console.time function starts a timer with the label supplied as an argument to the function, while the console.timeEnd function stops a timer with the label supplied as an argument to the function.

      console.time('<timer-label>');
      console.timeEnd('<timer-label>');
      

      We can use it to figure out how much time it took to run an operation by passing in the same label name to both functions.

      const users = ['Vivaldi', 'Beethoven', 'Ludovico'];
      
      const loop = (array) => {
        array.forEach((element, idx) => {
          console.log(element);
        })
      }
      
      const timer = () => {
        console.time('timerLabel');
        loop(users);
        console.timeEnd('timerLabel');
      }
      
      timer();
      

      We can see the timer label displayed against time value after the timer is stopped.

      Output

      Vivaldi Beethoven Ludovico timerLabel: 0.69091796875ms

      It took the loop function 0.6909ms to finish looping through the array.

      Conclusion

      At last, we’ve come to the end of this tutorial.

      Note that this tutorial did not cover non-standard uses of the console class like console.profile, console.profileEnd, and console.timeLog.



      Source link