Is there a way to auto expand objects in Chrome Dev Tools?
Asked Answered
M

16

192

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?

Misvalue answered 5/5, 2012 at 18:38 Comment(2)
Not at the moment. Feel free to file a feature request at 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 ;))Therewithal
bugs.webkit.org/show_bug.cgi?id=61427Constitutionally
A
54

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.

Amidst answered 22/12, 2014 at 20:47 Comment(2)
Here is the typescript version I use: gist.github.com/mathieucaroff/6851b295c1e4bffafce362d0a1ae00f0Catwalk
Yes! Thank you so much! console.table is great and all, but fails miserably with arrays in arrays.Mena
G
113

Consider using console.table().

console.table output

Gabrila answered 6/11, 2014 at 13:44 Comment(3)
Looks nice! But it shrinks wide values if there are 10+ keys :(Bedford
Be careful not to deploy this to browsers in production that may not have it without checking for its existance.Precipitin
This only expands objects at a depth level of 1. It's a shallow expansion, and it does not expand nested objects.Woodcraft
F
90

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).

Freestanding answered 17/3, 2015 at 3:55 Comment(4)
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...Inaccessible
this gives the Uncaught ReferenceError: _ is not defined errorLarina
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.Mcgray
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.Woodcraft
A
54

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.

Amidst answered 22/12, 2014 at 20:47 Comment(2)
Here is the typescript version I use: gist.github.com/mathieucaroff/6851b295c1e4bffafce362d0a1ae00f0Catwalk
Yes! Thank you so much! console.table is great and all, but fails miserably with arrays in arrays.Mena
B
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.

Brennen answered 28/5, 2012 at 3:3 Comment(2)
Couple this with Adding custom functionality into chrome's console and we can have pretty(a) in all sites at all times ;)Edmundson
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 reliefMisusage
V
11

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

Villus answered 23/7, 2014 at 4:20 Comment(0)
W
10

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

Woodcraft answered 13/4, 2019 at 19:21 Comment(0)
S
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);
Slogan answered 6/3, 2016 at 1:8 Comment(0)
B
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,'$'))
Brana answered 22/4, 2016 at 16:31 Comment(0)
D
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)

Dysphemism answered 8/12, 2018 at 14:49 Comment(0)
E
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.

Eirena answered 5/9, 2014 at 18:28 Comment(0)
G
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.

Grizzled answered 10/8, 2018 at 8:57 Comment(0)
U
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

Unkind answered 15/7, 2021 at 23:14 Comment(0)
D
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
Day answered 6/9, 2021 at 22:40 Comment(0)
D
0

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

Dishearten answered 30/11, 2022 at 10:48 Comment(0)
M
0

might try:

  • use tab and/or arrow keys to navigate
  • use space or enter or left/right arrow keys to expand/collpse

for small object/array, might also use:

j = (obj) => JSON.stringify(obj, null, 4)

or

o = (obj) => { const _o = { ...obj }; return _o }

to mimic expanding them


(reference: my reddit comment

Mastat answered 18/2 at 2:57 Comment(1)
wow, actually the console.table also works. (Just note that the output can only be shown in the inspect page of the worker itself, etcMastat
R
-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'

Rosellaroselle answered 20/2, 2016 at 17:21 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.