🏠 back to Observable

Feature Request: Save expand state of inspected variables w' notebook

It would be useful to be able to control the default state of inspected objects in a published notebook. If I publish the notebook with an object in an expanded state, then it should be in the expanded state when the notebook is first opened (of course the reader can change that state by clicking the arrow as usual). But the default appearance could/should be under the control of the notebook author.

I thought cells in notebooks recalled their open or closed states.

The question is not about cells being pinned or unpinned, it is about literal objects that are expanded or collapsed in the inspector (via the triangle arrow):

1 Like

Oh I see.

A work around for now would be to display that in the markdown.

rules = Object {
start: “${rules.start}”
subject: …

The point of using an actual object is that it can also be used directly in code. One shouldn’t have to choose between a nice display and a live object, as one might on a traditional web page. This is, for me, a primary reason to use observable in the first place…

As a workaround, you can use some other object pretty printer and stick the live-updating result with syntax highlighting into an html cell.

Here is what I worked out using prettier, https://observablehq.com/d/1f809eb181a12b8c

function pprint(obj, name) {
  let code = prettier_format(name ? 
    `${name} = (${JSON.stringify(obj)})` :
  return md`~~~js\n${code.slice(0, -2)}\n~~~`;
prettier_format = {
  let prettier =  await require('prettier@2', 'prettier@2/parser-babel.js');
  return str => prettier.format(str, {parser: "babel", plugins: [prettier]});

The resulting appearance isn’t precisely the same as the inspector, but should be comparable (this version also has the advantage that the output can be copy/pasted as valid code):

1 Like

Thanks @jrus (and @hellonearthis) - this seems a better temporary workaround, but still not nearly as intuitive/elegant as the feature request itself. Would be great to hear from someone on the observable team on this…

1 Like

I work at Observable and I totally agree, I was just wishing for this the other day.

Related: when you re-evaluate a JS object cell, the Inspector loses all but the top level open/closed state. So like, if you have a non-nested array that’s expanded, it’ll stay expanded if you update it. But if there’s a nested level that’s expanded, it’ll collapse. This makes it especially hard to monitor deeply-nested properties of fast-updating objects without pulling them out to another cell.

Also related: with our new Table input and its nice checkboxes to filter the values that get passed through using viewof, I’ve been wondering if we should have an analogous JavaScript object inspector “input” component that lets you configure display (in code), and (in the output) lets you select a child to use as the value of the cell.

Implementation-wise (and it’d be fair not to care about this, lol — it’s our problem), it’s a lil tricky to think where we’d store the state of the Inspector’s expansion. Currently, everything about the cell output is a pure function of the code in the cells. Saving which nodes are expanded would be a new kind of metadata to save with the cell. The Inspector lives in the isolated iframe where, for security reasons, all notebook content runs; it would have to pass those open/close events up to the parent to persist them. And that’s one specific case of the more general problem of persisting (non-code) notebook state, which comes up whenever a notebook gets to be more like a CRUD application. So the question of saving the expand state of inspected variables ends up bumping into the fundamental privacy divide between notebook content and notebook code, and making that membrane semi-permeable is a big question and topic of discussion for us lately.

Hope this helps somewhat… I’ve filed your request in our public feedback repo.


I guess I was thinking the expand state for an inspected object could be stored along with the pinned-state for the cell, but I’m probably not seeing the whole picture…
Anyhow, thanks for the detailed reply @tophtucker

It’s not functional, but the CSS seems to work.

You could use a viewof to have a custom visualisation, yet let the data “passthrough” so you can still read it as normal. You can parameterise the visualisation with additional options (e.g. the expansion state)

Is that a valid path do you think. It solves where does the state go because it is in the notebook source (but shared by all viewers)