185

EVERY SINGLE TIME I view an object in the console I am going to want to expand it, so it gets tiresome to have to click the arrow to do this EVERY SINGLE TIME :) Is there a shortcut or setting to have this done automatically?

Jeremy Smith
  • 14,727
  • 19
  • 67
  • 114
  • 6
    Not at the moment. Feel free to file a feature request at http://new.crbug.com (start the summary with the "DevTools: " prefix) but be very specific about _where_ and _which_ objects you want expanded. E.g., you **certainly** will never want to have ALL your objects expanded, since they may (a) have huge numbers of properties; (b) contain cycles (in the latter case it will take _a while_ to expand the entire tree ;)) – Alexander Pavlov May 05 '12 at 20:17
  • 3
    https://bugs.webkit.org/show_bug.cgi?id=61427 – NVI May 07 '12 at 14:53

15 Answers15

110

Consider using console.table().

console.table output

Gajus
  • 69,002
  • 70
  • 275
  • 438
84

To expand / collapse a node and all its children,

Ctrl + Alt + Click or Opt + Click on arrow icon

(note that although the dev tools doc lists Ctrl + Alt + Click, on Windows all that is needed is Alt + Click).

Nate
  • 2,449
  • 3
  • 21
  • 29
James
  • 1,071
  • 1
  • 11
  • 16
  • 3
    Testing this is in OSX chrome 46, it expands all the prototype object too, which makes it as bad as having to click on every arrow. Instead, you have to find the properties (hasOwn) in the middle of 50 prototype methods, properties etc... – Kev Oct 21 '15 at 20:25
  • this gives the Uncaught ReferenceError: _ is not defined error – MagePsycho Nov 02 '15 at 07:41
  • 5
    Just a side note. In the case of the objects with massive depth, Ctrl+Alt+Click should be applied a few times until it expands whole object, not only once. – BentCoder Jun 08 '17 at 11:16
  • Correctly answers the question. Although it still requires the user to manually click the object in the console, and the solution is not universally supported across browsers. – tim-montague Apr 13 '19 at 19:00
52

While the solution mentioning JSON.stringify is pretty great for most of the cases, it has a few limitations

  • It can not handle items with circular references where as console.log can take care of such objects elegantly.
  • Also, if you have a large tree, then ability to interactively fold away some nodes can make exploration easier.

Here is a solution that solves both of the above by creatively (ab)using console.group:

function expandedLog(item, maxDepth = 100, depth = 0){
    if (depth > maxDepth ) {
        console.log(item);
        return;
    }
    if (typeof item === 'object' && item !== null) {
        Object.entries(item).forEach(([key, value]) => {
            console.group(key + ' : ' +(typeof value));
            expandedLog(value, maxDepth, depth + 1);
            console.groupEnd();
        });
    } else {
        console.log(item);
    }
}

Now running:

expandedLog({
    "glossary": {
        "title": "example glossary",
        "GlossDiv": {
            "title": "S",
            "GlossList": {
                "GlossEntry": {
                    "ID": "SGML",
                    "SortAs": "SGML",
                    "GlossTerm": "Standard Generalized Markup Language",
                    "Acronym": "SGML",
                    "Abbrev": "ISO 8879:1986",
                    "GlossDef": {
                        "para": "A meta-markup language, used to create markup languages such as DocBook.",
                        "GlossSeeAlso": ["GML", "XML"]
                    },
                    "GlossSee": "markup"
                }
            }
        }
    }
})

Will give you something like:

output screenshot

The value of maxDepth can be adjusted to a desired level, and beyond that level of nesting - expanded log will fall back to usual console.log

Try running something like:

x = { a: 10, b: 20 }
x.x = x 
expandedLog(x)

enter image description here

Also please note that console.group is non-standard.

n-smits
  • 685
  • 7
  • 20
lorefnon
  • 12,875
  • 6
  • 61
  • 93
41

Might not be the best answer, but I've been doing this somewhere in my code.

Update:

Use JSON.stringify to expand your object automatically:

> a = [{name: 'Joe', age: 5}, {name: 'John', age: 6}]
> JSON.stringify(a, true, 2)
"[
  {
    "name": "Joe",
    "age": 5
  },
  {
    "name": "John",
    "age": 6
  }
]"

You can always make a shortcut function if it hurts to type all that out:

j = function(d) {
    return JSON.stringify(d, true, 2)
}

j(a)

Previous answer:

pretty = function(d)
{
  var s = []
  for (var k in d) {
    s.push(k + ': ' + d[k])
  }
  console.log(s.join(', '))
}

then, instead of:

-> a = [{name: 'Joe', age: 5}, {name: 'John', age: 6}]
-> a
<- [Object, Object]

You do:

-> a.forEach(pretty)
<- name: Joe, age: 5
   name: John, age: 6

Not the best solution, but works well for my usage. Deeper objects will not work so that's something that can be improved on.

gak
  • 32,061
  • 28
  • 119
  • 154
  • Couple this with [Adding custom functionality into chrome's console](http://stackoverflow.com/a/9051533/1287812) and we can have `pretty(a)` in all sites at all times ;) – brasofilo Oct 12 '14 at 01:21
  • Very helpful, thanks! The j() function gave me the idea to add a console log function as well. Maybe not a good idea in real code to kind of 'hide' the logs (ide has autocomplete anyway), but for just trying something in an online editor only having to type 'clj(v)' instead of 'console.log(j(v))' is a relief – Corrl Oct 29 '21 at 07:32
10

option+Click on a Mac. Just discovered it now myself and have made my week! This has been as annoying as anything

Hady
  • 2,597
  • 2
  • 29
  • 34
9

By default the console on Chrome and Safari browsers will output objects which are collapsed, with sorted property keys, and include all inherited prototype chains.

I'm personally not a fan. Most developers need raw output of an object without the prototype chain, and anything else should be opt-in. Collapsed objects waste the developer's time, because they need to expand them, and if they wanted less output they could just log the property keys they need. Auto-sorting the property keys, leaves the developer without a way to check if their own sort works correctly, which could cause bugs. And lastly, the common Javascript developer does not spend much time working on the inherited prototype chain, so that adds noise to the logs.

How to expand objects in Console

Recommended

  1. console.log(JSON.stringify({}, undefined, 2));

    Could also use as a function:

    console.json = object => console.log(JSON.stringify(object, undefined, 2));
    
    console.json({});
    
  2. "Option + Click" (Chrome on Mac) and "Alt + Click" (Chrome on Window)
    However, it's not supported by all browsers (e.g. Safari), and Console still prints the prototype chains, auto-sorts property keys, etc.

Not Recommended

I would not recommend either of the top answers

  1. console.table() - this is shallow expansion only, and does not expand nested objects

  2. Write a custom underscore.js function - too much overhead for what should be a simple solution

tim-montague
  • 16,217
  • 5
  • 62
  • 51
8

Here is a modified version of lorefnon's answer which does not depend on underscorejs:

var expandedLog = (function(MAX_DEPTH){

    return function(item, depth){

        depth    = depth || 0;
        isString = typeof item === 'string'; 
        isDeep   = depth > MAX_DEPTH

        if (isString || isDeep) {
            console.log(item);
            return;
        }

        for(var key in item){
            console.group(key + ' : ' +(typeof item[key]));
            expandedLog(item[key], depth + 1);
            console.groupEnd();
        }
    }
})(100);
Michaelangel007
  • 2,798
  • 1
  • 25
  • 23
Haringat
  • 81
  • 1
  • 1
2

Here is my solution, a function that iterates an all the properties of the object, including arrays.

In this example I iterate over a simple multi-level object:

    var point = {
            x: 5,
            y: 2,
            innerobj : { innerVal : 1,innerVal2 : 2 },
            $excludedInnerProperties : { test: 1},
            includedInnerProperties : { test: 1}
        };

You have also the possibility to exclude the iteration if the properties starts with a particular suffix (i.e. $ for angular objects)

discoverProperties = function (obj, level, excludePrefix) {
        var indent = "----------------------------------------".substring(0, level * 2);
        var str = indent + "level " + level + "\r\n";
        if (typeof (obj) == "undefined")
            return "";
        for (var property in obj) {
            if (obj.hasOwnProperty(property)) {
                var propVal;
                try {
                    propVal = eval('obj.' + property);
                    str += indent + property + "(" + propVal.constructor.name + "):" + propVal + "\r\n";
                    if (typeof (propVal) == 'object' && level < 10 && propVal.constructor.name != "Date" && property.indexOf(excludePrefix) != 0) {
                        if (propVal.hasOwnProperty('length')) {
                            for (var i = 0; i < propVal.length; i++) {
                                if (typeof (propVal) == 'object' && level < 10) {
                                    if (typeof (propVal[i]) != "undefined") {
                                        str += indent + (propVal[i]).constructor.name + "[" + i + "]\r\n";
                                        str += this.discoverProperties(propVal[i], level + 1, excludePrefix);
                                    }
                                }
                                else
                                    str += indent + propVal[i].constructor.name + "[" + i + "]:" + propVal[i] + "\r\n";
                            }
                        }
                        else
                            str += this.discoverProperties(propVal, level + 1, excludePrefix);
                    }
                }
                catch (e) {
                }
            }
        }
        return str;
    };


var point = {
        x: 5,
        y: 2,
        innerobj : { innerVal : 1,innerVal2 : 2 },
        $excludedInnerProperties : { test: 1},
        includedInnerProperties : { test: 1}
    };

document.write("<pre>" + discoverProperties(point,0,'$')+ "</pre>");

Here is the output of the function:

level 0
x(Number):5
y(Number):2
innerobj(Object):[object Object]
--level 1
--innerVal(Number):1
--innerVal2(Number):2
$excludedInnerProperties(Object):[object Object]
includedInnerProperties(Object):[object Object]
--level 1
--test(Number):1

You can also inject this function in any web page and copy and analyze all the properties, try in on the google page using the chrome command:

discoverProperties(google,0,'$')

Also you can copy the output of the command using the chrome command:

copy(discoverProperties(myvariable,0,'$'))
Matteo Conta
  • 1,423
  • 13
  • 17
2

if you have a big object, JSON.stringfy will give error Uncaught TypeError: Converting circular structure to JSON , here is trick to use modified version of it

JSON.stringifyOnce = function(obj, replacer, indent){
    var printedObjects = [];
    var printedObjectKeys = [];

    function printOnceReplacer(key, value){
        if ( printedObjects.length > 2000){ // browsers will not print more than 20K, I don't see the point to allow 2K.. algorithm will not be fast anyway if we have too many objects
        return 'object too long';
        }
        var printedObjIndex = false;
        printedObjects.forEach(function(obj, index){
            if(obj===value){
                printedObjIndex = index;
            }
        });

        if ( key == ''){ //root element
             printedObjects.push(obj);
            printedObjectKeys.push("root");
             return value;
        }

        else if(printedObjIndex+"" != "false" && typeof(value)=="object"){
            if ( printedObjectKeys[printedObjIndex] == "root"){
                return "(pointer to root)";
            }else{
                return "(see " + ((!!value && !!value.constructor) ? value.constructor.name.toLowerCase()  : typeof(value)) + " with key " + printedObjectKeys[printedObjIndex] + ")";
            }
        }else{

            var qualifiedKey = key || "(empty key)";
            printedObjects.push(value);
            printedObjectKeys.push(qualifiedKey);
            if(replacer){
                return replacer(key, value);
            }else{
                return value;
            }
        }
    }
    return JSON.stringify(obj, printOnceReplacer, indent);
};

now you can use JSON.stringifyOnce(obj)

Wasim A.
  • 9,660
  • 22
  • 90
  • 120
1

Its a work around, but it works for me.

I use in the case where a control/widget auto updates depending on user actions. For example, when using twitter's typeahead.js, once you focus out of the window, the dropdown disappears and the suggestions get removed from the DOM.

In dev tools right click on the node you want to expand enable break on... -> subtree modifications, this will then send you to the debugger. Keep hitting F10 or Shift+F11 untill you dom mutates. Once that mutates then you can inspect. Since the debugger is active the UI of Chrome is locked and doesn't close the dropdown and the suggestions are still in the DOM.

Very handy when troubleshooting layout of dynamically inserted nodes that are begin inserted and removed constantly.

lcornejo
  • 79
  • 4
0

Another easier way would be

  • Use JSON.stringify(jsonObject)
  • Copy and Paste the result to Visual Studio Code
  • Use Ctrl+K and Ctrl+F to format the result
  • You will see formatted expanded object

I have tried this for simple objects.

user992867
  • 65
  • 4
0

You can package JSON.stringify into a new function eg

jsonLog = function (msg, d) {
  console.log(msg + '\n' + JSON.stringify(d, true, 2))
}

then

jsonLog('root=', root)

FWIW. Murray

Murrah
  • 1,508
  • 1
  • 13
  • 26
0

For lazy folks

/**
 * _Universal extensive multilevel logger for lazy folks_
 * @param {any} value **`Value` you want to log**
 * @param {number} tab **Abount of `tab`**
 */
function log(value, tab = 4) {
  console.log(JSON.stringify(value, undefined, tab));
}

Usage

log(anything) // [] {} 1 true null
0

Alt-click will expand all child nodes in the Chrome console.

DrMcCleod
  • 3,865
  • 1
  • 15
  • 24
-2

You could view your element by accessing document.getElementsBy... and then right click and copy of the resulted object. For example:

document.getElementsByTagName('ion-app') gives back javascript object that can be copy pasted to text editor and it does it in full.

Better yet: right click on the resulted element - 'Edit as html' - 'Select all' - 'Copy' - 'Paste'

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129