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

て烟熏妆下的殇ゞ 提交于 2019-11-27 10:20:50
lorefnon

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 (uses the underscore.js library) that solves both of the above by creatively (ab)using console.group:

expandedLog = (function(){
    var MAX_DEPTH = 100;

    return function(item, depth){

        depth = depth || 0;

        if (depth > MAX_DEPTH ) {
            console.log(item);
            return;
        }

        if (_.isObject(item)) {
            _.each(item, function(value, key) {
            console.group(key + ' : ' +(typeof value));
            expandedLog(value, 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:

The value of MAX_DEPTH 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)

Note that underscore dependency can be readily removed - just extract the required functions from the source.

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

Consider using console.table().

James

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

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.

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

Haringat

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

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

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.

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)

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.

I'm really not a fan of how Chrome and Safari consoles objects (over-engineered). Console by default condenses the object, sorts the object keys when the object is expanded, and shows the internal functions from the prototype chain. These features should be opt-in settings. Developers by default are probably interested in the raw results so they can check if their code is working correctly; and these features slow down development, and give incorrect sort results.

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 type 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

You can see here:

https://www.angularjswiki.com/angular/how-to-read-local-json-files-in-angular/

Easiest way:

import SampleJson from '../../assets/SampleJson.json';
...
console.log(SampleJson);

You must also add following code to tsconfig:

{  "compilerOptions": {  ..."resolveJsonModule": true, "esModuleInterop": true... } }

I claim no ownership of this, just referring a helpful source.

katrinsharp

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'

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!