DEV Community

Paul Oms
Paul Oms

Posted on

The trick to making console.log play nice with complex objects

console.log is useful in a lot of situations (although there are usually better ways to debug if that's what you're doing).

In the browser console.log works well with objects, you can drill down as much as you need. But in Node.js, when you look at the output of a nested object, you'll often see this:

$ console.log({a: {b: { c: {d: {}}}}})

{ a: { b: { c: [Object] } } }
Enter fullscreen mode Exit fullscreen mode

d: {} was replaced with [Object]. But why?

It's because the command line / terminal doesn't have a nice UI for drilling down, so Node attempts to print up to three levels deep. Beyond three levels it just prints [Object].

This is controlled by a variable in the node 'util' module, called depth, which defaults to 2. You can set it yourself here:

require('util').inspect.defaultOptions.depth = 0; // top level only, e.g.:
// { a: [Object] }
require('util').inspect.defaultOptions.depth = null; // print everything, e.g.: 
// {
//  a: { b: { c: { d: {} } } }
// }
Enter fullscreen mode Exit fullscreen mode

It's not a great idea to change an underlying variable, as it might come back to bite later. So a cleaner way is to convert the JSON object to a string and log that. We can use node's built in JSON class and the stringify method:

complexObject = {a: {b: { c: {d: {}}}}}
console.log(JSON.stringify(complexObject, null, 2))

// {
//   "a": {
//     "b": {
//       "c": {
//         "d": {}
//       }
//     }
//   }
// }
Enter fullscreen mode Exit fullscreen mode

Note that the 3rd parameter of JSON.stringify, Number 2, controls the number of spaces of indentation, and the 2nd parameter can be used to filter or adjust the objects and properties shown.

Now you can really see what's in those deep Objects.

Top comments (8)

Collapse
 
pcjmfranken profile image
Peter Franken • Edited

Or better yet console.dir(obj, { depth: null }) :)

Collapse
 
tracygjg profile image
Tracy Gilmore • Edited

Using JSON.stringify is useful in most cases but has limitations. There are some data types that JSON does not support well such as Dates. In complicated scenarios there is also a risk the object could contain a circular reference. I.e. a reference to a child object within the parent.
Reference MDN for more details on the Console API. developer.mozilla.org/en-US/docs/W...

Collapse
 
jeremybradbury profile image
Jeremy Bradbury

I'm with Peter on console.dir & TJ prettifying JSON can cause other problems.

The depth to null, is not great, but perhaps 5... You shouldn't rly allow infinite depth.

And ideally just log obj.a.b instead or use console log how it was intended: console.log('label for line', obj.a, obj.a.b, obj.a.b.c, obj.a.b.c.d)

Collapse
 
user_97530cf790 profile image
user_97530cf790

Thank you for the info. I was using the JSON.stringify but I didn't know that it can take second and third parameter. Indentation it's really cool.

Collapse
 
ehlo_250 profile image
Paul Oms

Thanks! You can do quite a lot with the 2nd/3rd params, probably too much! developer.mozilla.org/en-US/docs/W...

Collapse
 
pierrewahlberg profile image
Pierre Vahlberg

Wow, how have I been using JS on the backend and not known about this.. thanks!

Collapse
 
flameoftheforest profile image
Bryan Chong

personally, i find JSON.stringify(...) a hassle, i like your approach.

Collapse
 
7wp profile image
Robbie

You can try this console.log() no-fuss drop-in replacement that handles this and more: npmjs.com/package/console-log-json