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

Google Chrome-Devtools

Google Chrome-Devtools Problem Overview


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?

Google Chrome-Devtools Solutions


Solution 1 - Google Chrome-Devtools

Consider using console.table().

console.table output

Solution 2 - Google Chrome-Devtools

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

Solution 3 - Google Chrome-Devtools

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.

Solution 4 - Google Chrome-Devtools

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.

Solution 5 - Google Chrome-Devtools

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

Solution 6 - Google Chrome-Devtools

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

Solution 7 - Google Chrome-Devtools

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

I'm personally not a fan. Most developers need the raw output of an object, without the prototype chain. Condensing the object causes the developer to waste time expanding objects, and if they need less output they can just log the properties they need from code. Auto-sorting the property keys prevents the developer from checking if a bug or their own code caused the sort. And lastly, a common Javascript developer does not spend much time working on the inherited prototype chain, and showing that in console should be an opt-in feature.

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, object keys are auto-sorted when expanded, 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

Solution 8 - Google Chrome-Devtools

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,'$'))

Solution 9 - Google Chrome-Devtools

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)

Solution 10 - Google Chrome-Devtools

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.

Solution 11 - Google Chrome-Devtools

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.

Solution 12 - Google Chrome-Devtools

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

Solution 13 - Google Chrome-Devtools

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

Solution 14 - Google Chrome-Devtools

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'

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionJeremy SmithView Question on Stackoverflow
Solution 1 - Google Chrome-DevtoolsGajusView Answer on Stackoverflow
Solution 2 - Google Chrome-DevtoolsJamesView Answer on Stackoverflow
Solution 3 - Google Chrome-DevtoolslorefnonView Answer on Stackoverflow
Solution 4 - Google Chrome-DevtoolsgakView Answer on Stackoverflow
Solution 5 - Google Chrome-DevtoolsHadyView Answer on Stackoverflow
Solution 6 - Google Chrome-DevtoolsHaringatView Answer on Stackoverflow
Solution 7 - Google Chrome-Devtoolstim-montagueView Answer on Stackoverflow
Solution 8 - Google Chrome-DevtoolsMatteo ContaView Answer on Stackoverflow
Solution 9 - Google Chrome-DevtoolsWasim A.View Answer on Stackoverflow
Solution 10 - Google Chrome-DevtoolslcornejoView Answer on Stackoverflow
Solution 11 - Google Chrome-Devtoolsuser992867View Answer on Stackoverflow
Solution 12 - Google Chrome-DevtoolsMurrahView Answer on Stackoverflow
Solution 13 - Google Chrome-DevtoolspheianoxView Answer on Stackoverflow
Solution 14 - Google Chrome-DevtoolskatrinsharpView Answer on Stackoverflow