1560

I have this object:

const myObject = { "a":"a", "b":{ "c":"c", "d":{ "e":"e", "f":{ "g":"g", "h":{ "i":"i" } } } } }; 

But when I try to show it using console.log(myObject), I receive this output:

{ a: 'a', b: { c: 'c', d: { e: 'e', f: [Object] } } } 

How can I get the full object, including the content of property f?

5
  • 165
    Note that back in 2012 this was a problem in need of a solution, but this has (long) since been solved with the introduction of console.dir, which takes an options object that lets you specify the printing depth, with null for unlimited depth: console.dir(yourObject, { depth: null });. The highest voted answers for this question were all great answers back when they were written, but have since become obsolete over the course of a decade of improvements. The modern answer is simply "use console.dir". Commented Sep 11, 2021 at 17:44
  • 1
    I guess a best practice for StackOverflow users would be to use "Sorted by: Date modified (newest first)" if a question is old enough. Answer from mklement0 also suggests to use console.dir Commented Aug 21, 2023 at 20:14
  • console.dir is helpful but not as robust as console.log. The latter lets you log things like console.log("a", b, "c"). To get similar output with console.dir you'd need to do something like console.log("a"); console.dir(b); console.log("c"). Better yet (?), you could do this: console.log("a", util.inspect(b), "c") Commented May 18, 2024 at 20:36
  • 1
    Do this*: require('util').inspect.defaultOptions.depth = 10 In my case I have a pretty big project with all sorts of logging variability, like single and multiple parameter logging, strings, objects and all combinations of both. So console.dir wasn't an easy switch. That one-liner solved it. *That code smell a bit as changing inbuilt variables doesn't look right. Nonetheless, it solves the issue without the need to change and maintain the entire project's logging approach. No drawbacks so far. Use at your own risk though. Works in node 20, may break if they change it in future. Commented Jul 29, 2024 at 9:50
  • Better yet, import { inspect } from "node:util"; inspect.defaultOptions.depth = Infinity; because Infinity is a real thing in JS, and does what you expect it to do. Now your console.log won't redact itself, no matter how deeply nested your data is, nor how much you shouldn't have console logged it. You're in the driving seat. Commented Jan 14 at 15:35

22 Answers 22

2267

You need to use util.inspect():

const util = require('util') console.log(util.inspect(myObject, {showHidden: false, depth: null, colors: true})) // alternative shortcut console.log(util.inspect(myObject, false, null, true /* enable colors */)) 

Outputs

{ a: 'a', b: { c: 'c', d: { e: 'e', f: { g: 'g', h: { i: 'i' } } } } } 
Sign up to request clarification or add additional context in comments.

14 Comments

Nice solution. Though no need to specify {showHidden: false} as long as it defaults to false.
Good to know; not sure when it was introduced, but as of at least node v0.10.33 console.log() implicitly applies util.inspect() to its arguments, assuming the 1st one is not a format string. If you're happy with util.inspect()'s default options, simply console.log(myObject) will do - no need to require util; console.dir() does the same, but accepts only ` object to inspect; as of at least v0.11.14, you can pass the options object for util.inspect() as the 2nd argument; my answer has more details.
@mklement0 I have node v5.3.0 and when I console.log(obj) it still prints [Object] for deeply nested objects :( I really wish it would behave as you describe.
@SSH: console.log() is invariably limited to 2 levels (because it uses util.inspect()'s default without allowing you to change it); console.dir() has the same limit by default, but you can pass in an options object as the 2nd argument to change that (which is passed through to util.inspect(); note that console.dir() can only ever print 1 object at a time, however. To print with unlimited depth, use console.dir(myObject, { depth: null }).
console.dir(myObject, { depth: null }) is work for me
|
1013

You can use JSON.stringify, and get some nice indentation as well as perhaps easier to remember syntax.

console.log(JSON.stringify(myObject, null, 4)); 

{ "a": "a", "b": { "c": "c", "d": { "e": "e", "f": { "g": "g", "h": { "i": "i" } } } } } 

The third argument sets the indentation level, so you can adjust that as desired.

More detail here in JSON stringify MDN docs if needed.

10 Comments

also +1 for line breaks and indentation - almost always desired for me personally
Note that you cannot JSON.stringify objects with circular references. Like it would occur with DOM objects, for example. Stringify will throw an "Error: Converting circular structure to JSON".
this isn't the full object. objects containing only functions will be {}. Of course that may be a positive or a negative depending on what you want to print out.
console.log(JSON.stringify(myObject, null, 4)); pretty cool! https://gist.github.com/xgqfrms-GitHub/92aa2b00249f15084d24aa2e0a5d0300
It loses its color.
|
897

This answer draws on preexisting ones in an effort to provide a systematic overview.
Tip of the hat to Rory O'Kane and Mike 'Pomax' Kamermans for their help.

tl;dr

To get the desired output for the example in the question ad hoc, use console.dir():

console.dir(myObject, { depth: null }) // `depth: null` ensures unlimited recursion 

Why not util.inspect()? Because it’s already at the heart of diagnostic output: console.log() and console.dir() as well as the Node.js REPL use util.inspect() implicitly. It’s generally not necessary to require('util') and call util.inspect() directly - unless you want to capture the object visualization in a variable rather than printing to the console (e.g., let s = util.inspect(myObject, { depth: null }))

Alternatively, set the default depth to null:

const util = require('util') // or: import util from 'util' // Set the default depth to null to remove the recursion limit. // All subsequent console.log() and console.dir() calls will use this default. util.inspect.defaultOptions.depth = null console.log(myObject) // or: console.dir(myObject) 

Note: At least in recent Node.js versions, Infinity works in lieu of null too.

Details below.


  • console.log() (and its alias, console.info()):

    • If the 1st argument is NOT a format string: util.inspect() is automatically applied to every argument:
      • o = { one: 1, two: 'deux', foo: function(){} }; console.log(o, [1,2,3]) // -> '{ one: 1, two: 'deux', foo: [Function] } [ 1, 2, 3 ]'
      • Note that you cannot pass options through util.inspect() in this case, which implies 2 notable limitations:
        • Structural depth of the output is limited to 2 levels (the default).
          • Since you cannot change this with console.log(), you must instead use console.dir(): console.dir(myObject, { depth: null } prints with unlimited depth; see below.
        • You can’t turn syntax coloring on.
    • If the 1st argument IS a format string (see below): uses util.format() to print the remaining arguments based on the format string (see below); e.g.:
      • o = { one: 1, two: 'deux', foo: function(){} }; console.log('o as JSON: %j', o) // -> 'o as JSON: {"one":1,"two":"deux"}'
      • Note:
        • There is NO placeholder for representing objects util.inspect()-style.
        • JSON generated with %j is NOT pretty-printed.
  • console.dir():

    • Accepts only 1 argument to inspect, and always applies util.inspect() – essentially, a wrapper for util.inspect() without options by default; e.g.:
      • o = { one: 1, two: 'deux', foo: function(){} }; console.dir(o); // Effectively the same as console.log(o) in this case.
    • Node.js v0.11.14+: The optional 2nd argument specifies options for util.inspect() – see below; e.g.:
      • console.dir({ one: 1, two: 'deux'}, { colors: true }); // Node 0.11+: Prints object representation with syntax coloring.
  • The REPL: implicitly prints any expression's return value with util.inspect() with syntax coloring;
    i.e., just typing a variable's name and hitting Enter will print an inspected version of its value; e.g.:
    • o = { one: 1, two: 'deux', foo: function(){} } // The REPL echoes the object definition with syntax coloring.

util.inspect() automatically pretty-prints object and array representations, but produces multiline output only when needed.

  • The pretty-printing behavior can be controlled by the compact property in the optional options argument; false uses multi-line output unconditionally, whereas true disables pretty-printing altogether; it can also be set to a number (the default is 3) to control the conditional multi-line behavior – see the docs.

  • By default, output is wrapped at around 60 characters thanks, Shrey , regardless of whether the output is sent to a file or a terminal. In practice, since line breaks only happen at property boundaries, you will often end up with shorter lines, but they can also be longer (e.g., with long property values).

  • In v6.3.0+ you can use the breakLength option to override the 60-character limit; if you set it to Infinity, everything is output on a single line.

If you want more control over pretty-printing, consider using JSON.stringify() with a 3rd argument, but note the following:

  • Fails with objects that have circular references, such as module in the global context.
  • Methods (functions) will by design NOT be included.
  • You can't opt into showing hidden (non-enumerable) properties.
  • Example call:
    • JSON.stringify({ one: 1, two: 'deux', three: true}, undefined, 2); // creates a pretty-printed multiline JSON representation indented with 2 spaces

util.inspect() options object (2nd argument):

An optional options object may be passed that alters certain aspects of the formatted string; some of the properties supported are:

See the latest Node.js docs for the current, full list.

  • showHidden

    • if true, then the object's non-enumerable properties [those designated not to show up when you use for keys in obj or Object.keys(obj)] will be shown too. Defaults to false.
  • depth

    • tells inspect how many times to recurse while formatting the object. This is useful for inspecting large complicated objects. Defaults to 2. To make it recurse indefinitely, pass null.
  • colors

    • if true, then the output will be styled with ANSI color codes. Defaults to false. Colors are customizable [… – see link].
  • customInspect

    • if false, then custom inspect() functions defined on the objects being inspected won't be called. Defaults to true.

util.format() format-string placeholders (1st argument)

Some of the supported placeholders are:

See the latest Node.js docs for the current, full list.

  • %s – String.
  • %d – Number (both integer and float).
  • %j – JSON.
  • %% – single percent sign (‘%’). This does not consume an argument.

7 Comments

One way to simplify this would be to do a small named function to do console.dir(...) without all the typing: show = (v, depth=null)=> console.dir(v,{depth:depth}) and then call it like so show(variable) or show(variable, depth=1).
Thanks for this complete answer => THE BEST SOLUTION YOU GAVE : JSON.stringify({ one: 1, two: 'deux', three: true}, undefined, 2);
undefined also works: console.dir(myObject, { depth: undefined })
How do you save console.dir output into a string?
Thanks, @Mike'Pomax'Kamermans - I've updated the top section accordingly.
|
90

Since Node.js 6.4.0, this can be elegantly solved with util.inspect.defaultOptions:

require("util").inspect.defaultOptions.depth = null; console.log(myObject); 

1 Comment

Note that Infinity rather than null does the same thing but makes it much more obvious what we're actually doing.
78

Try this:

console.dir(myObject,{depth:null}) 

docs: MDN: console.dir

Comments

74

Another simple method is to convert it to json

console.log('connection : %j', myObject); 

6 Comments

Nice trick but the output won't be prettified, which makes it hard to read for large objects (the point of the question).
still very useful, and quicker to copy and paste into jsonlint.com than requiring utils :)
I think this one is great when you have an editor that will format json for you but you just need to copy it out from REPL
This is very handy and helpful if the object is small
The OP is already doing that. I am surprised there are upvotes on this answer when it's essentially a repeat of the OP's unresolved situation.
|
35

Both of these usages can be applied:

// more compact, and colour can be applied (better for process managers logging) console.dir(queryArgs, { depth: null, colors: true }); // get a clear list of actual values console.log(JSON.stringify(queryArgs, undefined, 2)); 

Comments

32

perhaps console.dir is all you need.

http://nodejs.org/api/console.html#console_console_dir_obj

Uses util.inspect on obj and prints resulting string to stdout.

use util option if you need more control.

2 Comments

As of (at least) v0.11.14, you can pass an options object as the 2nd argument, which is passed to util.inspect().
27

A good way to inspect objects is to use node --inspect option with Chrome DevTools for Node.

node.exe --inspect www.js 

Open chrome://inspect/#devices in chrome and click Open dedicated DevTools for Node

Now every logged object is available in inspector like regular JS running in chrome.

enter image description here

There is no need to reopen inspector, it connects to node automatically as soon as node starts or restarts. Both --inspect and Chrome DevTools for Node may not be available in older versions of Node and Chrome.

2 Comments

A message for me: try that out -> node.exe --inspect index.js
This should be on top. best answer. :)
22

You can also do

console.log(JSON.stringify(myObject, null, 3)); 

Comments

14

I think this could be useful for you.

const myObject = { "a":"a", "b":{ "c":"c", "d":{ "e":"e", "f":{ "g":"g", "h":{ "i":"i" } } } } }; console.log(JSON.stringify(myObject, null, '\t'));

As mentioned in this answer:

JSON.stringify's third parameter defines white-space insertion for pretty-printing. It can be a string or a number (number of spaces).

Comments

11

Use a logger

Don't try to reinvent the wheel

util.inspect(), JSON.stringify() and console.dir() are useful tools for logging an object while playing in the browser console.

If you are serious about Node.js development, you should definitely use a logger. Using it you can add all the logs you want for debugging and monitoring your application. Then just change the logging level of your logger to keep only the production logs visible.

Additionaly they have already solved all the annoying issues related to logging, like: circular objects, formatting, log levels, multiple outputs and performance.

Use a modern logger

pino is a fast and modern logger for Node.js that has sane defaults to handle circular object/references like depthLimit and edgeLimit. It supports child loggers, transports and a pretty printed output.

Moreover, it has 8 default logging levels that you can customize using the customLevels option:

  • fatal
  • error
  • warn
  • info
  • debug
  • trace
  • silent

Install it

npm install pino 

Use it

const logger = require('pino')() logger.info('hello world') 

Configure it

const logger = pino({ depthLimit: 10, edgeLimit: 200, customLevels: { foo: 35 } }); logger.foo('hi') 

Comments

9

JSON.stringify()

let myVar = {a: {b: {c: 1}}}; console.log(JSON.stringify( myVar, null, 4 )) 

Great for deep inspection of data objects. This approach works on nested arrays and nested objects with arrays.

Comments

9

You can simply add an inspect() method to your object which will override the representation of object in console.log messages

eg:

var myObject = { "a":"a", "b":{ "c":"c", "d":{ "e":"e", "f":{ "g":"g", "h":{ "i":"i" } } } } }; myObject.inspect = function(){ return JSON.stringify( this, null, ' ' ); } 

then, your object will be represented as required in both console.log and node shell


Update:

object.inspect has been deprecated ( https://github.com/nodejs/node/issues/15549). Use myObject[util.inspect.custom] instead:

const util = require('util') var myObject = { /* nested properties not shown */ } myObject[util.inspect.custom] = function(){ return JSON.stringify( this, null, 4 ); } console.log(util.inspect(myObject)) 

Comments

6

If you're looking for a way to show the hidden items in you array, you got to pass maxArrayLength: Infinity

console.log(util.inspect(value, { maxArrayLength: Infinity })); 

1 Comment

Also works with console.dir.
5

A simple trick would be use debug module to add DEBUG_DEPTH=null as environment variable when running the script

Ex.

DEBUG=* DEBUG_DEPTH=null node index.js

In you code

const debug = require('debug'); debug("%O", myObject); 

1 Comment

@Bala You will need to install "debug" module in your project "npm install debug --save"
5
const myObject = { "a":"a", "b":{ "c":"c", "d":{ "e":"e", "f":{ "g":"g", "h":{ "i":"i" } } } } }; console.log(JSON.stringify(myObject)); 

Output:

{"a":"a","b":{"c":"c","d":{"e":"e","f":{"g":"g","h":{"i":"i"}}}}} 

1 Comment

Warning: JSON.stringify has limitations: - can't display all variable types: functions, Symbol, BigInt... - crashes on circular references
4

Easiest option:

 console.log('%O', myObject);

1 Comment

This doesn't solve the problem of printing myObject to an arbitrary depth
3

Replace the default console by a customized console as following:

globalThis.console = new console.Console({ inspectOptions: { depth:null, }, stdout:process.stdout, stderr:process.stderr, }); 

Once the code block is executed, all output of the console.log is formatted as you specified in the inspectOptions.

If you already have a large amount of code which uses console.log, replacing console might be the easiest way to solve the problem.

Accoding to the official reference of Node.js, creating customized consoles as new Console(options) have been available since Node.js version 8.

2 Comments

See top comment on the question about using console.dir!
Asher, this solution might be intended not only to solve the problem but to minimize your code modification.
2

The node REPL has a built-in solution for overriding how objects are displayed, see here.

The REPL module internally uses util.inspect(), when printing values. However, util.inspect delegates the call to the object's inspect() function, if it has one.

Comments

0

My way :)

Define function

console.obj = (...args) => args.forEach(obj => console.log(require('util').inspect(obj, false, null, true))); 

Usage

const test = { "a":"a", "b":{ "c":"c", "d":{ "e":"e", "f":{ "g":"g", "h":{ "i":"i" } } } } }; const test2 = { second: 'object' }; console.obj(test, test2); 

Comments

0

For NodeJs 16 and beyond, you can use the below snippet.

require(util).inspect(<your-object-here>, { showHidden: false, depth: null, maxArrayLength: null, maxStringLength: null }) 

Comments