
Console.table() - koolba
https://developer.mozilla.org/en-US/docs/Web/API/Console/table
======
azinman2
This is a great example that shows how poor most non-web debugging and
logging. The ability to mix and match data types and presentation format is
extremely useful. Almost everywhere else we just have printf. And that’s
printf going to stdout — there isn’t a universally deployed format to even
allow it to travel easily over the network and be viewed on one of many useful
and advanced viewers.

I think part of the problem is that programmers rarely want to get into these
supportive details; they just printf and get on with it.

~~~
westoncb
Damn, glad to see this, but they're also kinda encroaching on my territory! :P

I've been working on something like this that's language agnostic and works
with not only tables but also trees, graphs, lists, hashmaps, etc., and
animates the visuals as the data structures are modified in real time (and you
can pause, playback, step, etc.):
[http://symbolflux.com/projects/avd](http://symbolflux.com/projects/avd)

The api I was conceiving earlier was more complex, but if you read the copy
there, you'll notice it's essentially the same now: `MObject.monitor(...)` or
MTable.monitor() MStateMachine.monitor() etc.

Edit: really am happy to see some other projects like this in total, partly
because I want to use 'em now if possible—but also because I've had a
surprisingly hard time communicating to other developers why it might be
desirable to do something like this in the first place, so I'll be very happy
to have general awareness raised.

I read the first line of their docs as rather dry humor, "Displays tabular
data as a table." —like yeah, of course you would want to see tabular data as
a table, and hierarchical data as a tree, etc.!

~~~
Zalastax
At a quick glance it looks like it's targeted towards mutable data structures.
Can it support (and would it make sense to support) immutable data? E.g. it
would be nice to have a Haskell state monad that also visualizes its state.

~~~
westoncb
You are correct, it's very much targeted toward mutable data structures. It'd
be interested in looking more into the state monad and considering the
possibilities, but I haven't yet.

Actually part of how I see the role of systems like this is part of the
necessary conditions for more safely working with mutable data. I think
mutable data is more risky, but also super easy to work with, so if we had
ways of making it more reliable we should explore them. I envision languages
where this sort of visualization is a core feature designed in tandem with the
runtime etc.

~~~
Zalastax
Neat! Very interesting ideas! The Vacuum package[1] seems like something you
could look into if you want to explore Haskell. Good luck with your project!

[1]:
[https://hackage.haskell.org/package/vacuum](https://hackage.haskell.org/package/vacuum)

~~~
westoncb
Thanks! Looks pretty cool. I also found this: [http://felsin9.de/nnis/ghc-
vis/](http://felsin9.de/nnis/ghc-vis/)

------
nicusor
Another useful trick I've been using for some time is

console.log({ a, b })

where _a_ and _b_ are some variables. This will print the name of the variable
next to its value. So it can be thought as a faster version of

console.log('a: ' \+ a)

~~~
foreigner
Nice! Thank you

~~~
anonytrary
Completely tangential, but you can also do the opposite with nesting, which I
learned about literally yesterday:

const { some: { nested: { field } } } = tree; // field ===
tree.some.nested.field

or rename things while you destructure them:

const { crappyFieldName: betterName } = myObject; // betterName ===
myObject.crappyFieldName

Now I can't stop using this feature...

------
kaycebasques
List of console.* methods in Chrome DevTools:
[https://developers.google.com/web/tools/chrome-
devtools/cons...](https://developers.google.com/web/tools/chrome-
devtools/console/console-reference)

------
anthonybullard
Thanks for the tip to this, never really explored the console API deeper than
log. This is actually very useful

~~~
oatmealsnap
Yea, I can't believe this is the first time that I'm seeing this.

~~~
jaaames
There are a bunch of other console logging utils that are worth checking out.
time and timeEnd are one of my favorite.

------
quirkot
ThereThere.table()

ThingsWillGetBetter.table()

INeverLikedHimAnyway.table()

~~~
pvinis
I didn't get the reference. Some help?

~~~
jayrhynas
CONsole, the noun, vs conSOLE, the verb (to comfort at a time of grief or
disappointment)

------
smileypete
Some indentation can make logs more readable:

    
    
        :71: 04:09:04.26 Added to trace list: All
       :271: 04:09:04.26 ----v
       :271: 04:09:04.26     TestProcessTickFiles: 
        :97: 04:09:04.26     ----v
        :97: 04:09:04.26         SetupTickFileProcessing: 
       :157: 04:09:04.26         ----v
       :157: 04:09:04.26             GetNumLines: 
       :161: 04:09:04.26             Returning number of lines as: 752
       :161: 04:09:04.26         ^----
       :140: 04:09:04.26     ^----
       :277: 04:09:04.26 ^----
    

As well as log functions that output arrays, in some applications being able
to log state machine changes can be handy too.

~~~
Doxin
Chrome devtools has support for logging groups, which indent and allow
collapsing.

~~~
porker
Never knew that, thanks.

------
nadavami
This is a really good one to remember, and it's also implemented in node which
can be handy for making little CLI tools.

------
anonytrary
I was just playing around in node a few days ago, and had to mock some console
statements. I stumbled upon this exact API and played with the output bit.
It's a useful feature I never knew about in my years of doing javascript and
it's kind of surreal to see it on the top of HN just a few days later!

------
mrmagooey
I made something similar as a fun little project
[https://github.com/mrmagooey/taboo](https://github.com/mrmagooey/taboo), does
the same print function but also does some basic querying, deletes and
updates, left and inner joins. I had no idea that the inbuilt version existed
though.

------
samspenc
Is this supported in other browsers as well?

~~~
TehCorwiz
Yes, both Chrome and Edge support it, as well as Safari and Opera.

The Fine Article includes a compatibility chart at the bottom

------
umaar
Some other Console tips in DevTools:
[https://www.google.com/search?q=site%3Ahttps%3A%2F%2Fumaar.c...](https://www.google.com/search?q=site%3Ahttps%3A%2F%2Fumaar.com%2Fdev-
tips+console+panel)

------
DonHopkins
Recently I've been working on kind of the converse of this problem with JSON
and spreadsheets, and I'll briefly describe it here (and I'll be glad to share
the code), in the hopes of getting some feedback and criticism:

How can you conveniently and compactly represent, view and edit JSON in
spreadsheets, using the grid instead of so much punctuation?

The goal is to be able to easily edit JSON data in any spreadsheet, copy and
paste grids of JSON around as TSV files (the format that Google Sheets puts on
your clipboard), and efficiently import and export those spreadsheets as JSON.

It's especially powerful with Google Sheets, since you can run JavaScript code
in them to import, export and validate JSON, and other apps can easily
retrieve those spreadsheets as TSV files, which are super-easy to parse into
2D arrays of strings to convert to JSON.

This is a new reimplementation of some old ideas I've been happily using for
years with Python and CSV files, plus some new ideas. But now it's general
purpose, JSON oriented, written in JavaScript, integrated with Google Sheets,
and I'm releasing it as open source once I get it into working shape.

Here is an example spreadsheet, which includes several sheets of different
structures, and a script to convert the spreadsheet to JSON.

[https://docs.google.com/spreadsheets/d/1nh8tlnanRaTmY8amABgg...](https://docs.google.com/spreadsheets/d/1nh8tlnanRaTmY8amABggxc0emaXCukCYR18EGddiC4w/edit?usp=sharing)

The first sheet "world" is the top level object, which configures a Unity3D
app scripted in JavaScript (that's UnityJS, another story, but just think of
this JSON as an arbitrary example). So the world is a big fancy JSON structure
used by JavaScript code to create and configure a bunch of prefabs.

As you can obviously see, you just write your JSON expressions as an indented
outline with type names before the values, putting keys, types and values in
separate indented cells.

    
    
        object
            tileRows       number 1
            tileColumns    number 2
            materialTiling object
                           x      number 4
                           y      number 4
            materialOffset object
                           x      number 0.5
                           y      number 0.5
            ...
    

You can use the "sheet" pseudo-type to make references to objects, arrays,
etc, defined in other named sheets of the same spreadsheet:

    
    
            texturePaths       sheet texturePaths
            prefabMap          sheet prefabMap
            bowConfigs_outline sheet bowConfigs_outline
            bowConfigs         sheet bowConfigs_table
            ...
    

There's another sheet named texturePaths that contains an array of strings:

    
    
        array
              string Abstract_001
              string Abstract_002
              string Abstract_003
              ...
    

And the prefabMap sheet is just a map of different types of content,
directories and file names. You can represent any kind of JSON structures in
the spreadsheets, and it's much easier to edit than raw JSON text.

Also, there are some convenient ways of compactly representing repetitive
structured data.

One common type is a 2d array of elements all the same type, which you can
make with the "grid" pseudo-type:

    
    
            tileName grid          string    10        10
                     Hex_Sea       Hex_Sand  Hex_Magma ...
                     Hex_Grass_Dry Hex_Magma Hex_Sand  ...
                     ...           ...       ...       ...
    

That's a 10x10 grid of strings. You can also make grids of other types that
will fit into one cell. For example, you could make a grid of strings or
numbers or booleans, but not arrays or objects, since they don't fit in a
single cell. But you could make a grid of the "sheet" pseudo-type, with a grid
of sheet names, each sheet each containing any type or pseudo-type of object.

It also supports a "json" pseudo type that lets you put an arbitrary JSON
expression into one cell.

Notice that the values themselves may be calculated by spreadsheet formula,
which call any function or refer to any cells in any other sheet. In this
example, each tile name is calculated by randomly choosing from a range
pointing to all the hex tile names in the prefabMap:

=index(prefabMap!$E$5:$E$26, RANDBETWEEN(1, counta(prefabMap!$E$5:$E$26)))

You can write comments and intermediate values and formulas off to the right
of the JSON data, or in other spreadsheets, which the JSON data may ignore or
depend on.

The spreadsheet gives you enormous amounts of power to dynamically process the
resulting JSON! So you can publish spreadsheets connected to live data, and
import them as JSON.

Some people laugh at me when I say I prefer spreadsheets to outliners or even
text editors. I'd love it if there were a decent tree structures JSON editor
as powerful and ubiquitous as Google Sheets, but I've never heard of one. Tell
me if you have, please!

Userland Frontier (later Radio Userland) came close to that ideal, predating
and then adapting to both XML and JSON, but it never quite hit the mark of
what you can easily do with a spreadsheet.

Another great way of compactly representing repetitive JSON structures in a
spreadsheet is to use a table whose headers specify the structure, key names
and types of the JSON arrays and objects.

This is essentially what Console.table does with an array of objects, but with
rows and columns exchanged, and supporting arbitrarily nested arrays and
objects.

The "bowConfigs_outline" sheet has a conventional outline formatted array of
two JSON objects (rainbow bow configurations) that have the same structure. It
is 175 rows, and 9 columns (1575 cells, many empty, with many repeated types
and key names).

    
    
        array                    
            object                
                bowStart number 0    
                bowEnd number 0.8    
                bowHeight number 30    
                startWidth number 1    
                endWidth number 0    
                widthMultiplier number 5    
                fromLocalOffset object        
                    x number 6
                toLocalOffset object        
                    x number -6
                ...
    

The "bowConfigs_table_compact" sheet shows the compact table representation of
that same structure, with headers that implicitly describe the shape of the
structure so there is one value per column, with no rows or columns of wasted
space. It is only 4 rows (a row with the "table" type, a row with the headers,
plus one row for each structure), and 58 columns (232 cells, few empty, with
no unnecessarily repeated types or key names).

Lining all the values of the same name and type up in vertical columns makes
it really easy to view and edit the values, and apply spreadsheet formula to
dynamically calculate them! It would be much harder to track down and apply a
formula to each "bowEnd" property in the outline format.

(Shown here as comma separated values since the headers contain spaces and
that would be confusing.)

The top row is a series of columns of tokens, including [ and ] for arrays, {
and } for objects, and keys and types for the object and array elements. It's
like a simple horizontal schema that specifies the JSON structure, key names,
types and columns, so that nothing needs to be repeated, and no space is
wasted.

    
    
        table
        ,{ bowStart number,bowEnd number,bowHeight number,startWidth number,endWidth number,widthMultiplier number,fromLocalOffset { x number },toLocalOffset { x number },lineRenderer/startColor { r number,g number,b number },lineRenderer/endColor { r number,g number,b number },lineRenderer/alignment string,lineRenderer/widthCurve { animationCurveType string,keys [ { time number,value number }, ...
      
      ,0,0.8,30,1,0,5,6,-6,0.8782983063,0.7984165253,0.0370873959,0.7169641118,0.7843719274,0.3921475355,View,Keys,0,1,0.25,0.2,0.5,0.5,0.75,1,1,0,Blend,0,1,0.25,0.5,0.5,1,0.75,0.5,1,1,0,0.9368487271,0.6433703118,0.198860128,0.25,0.4861432977,0.5704963395,0.6107422953,0.5,0.9640410996,0.08846161285,0.05927839517,0.75,0.1199717053,0.2262674866,0.7876422776,1,0.6955264667,0.01858220912,0.7418451801

...

------
factorialboy
Chrome has had this for ages. But I am glad to see Firefox's dev tools making
improvements in recent times.

The only reason I stick with Chrome is the dev tools.

~~~
zeusly
This is mdn, it's not a showcase of firefox features but a web development
documentation for everyone. Firefox had this since at least v34 (2013).

------
mchahn
> Damn, glad to see this

Hmmm. I seem to remember seeing this a year or two ago. Didn't really find any
use for it.

------
dvh
Some time ago I saw bold font in console and I thought - why not render entire
website into console?

------
amelius
Is it possible to write interactive elements (e.g. buttons) to the console?

------
singularity2001
wow, already works in FF:

console.table({me:80,you:15,she:5})

 _thats_ why some people love JS!

~~~
ahoka
Because it has fancy debug printfs? Strange.

