Add cell to notebook from another cell

Sure that I just missed how to do this. How does one add a cell to the notebook programmatically from another cell?

Do you mean import?

There is no programmatic interface for editing notebooks. (At least, not currently.)

Not importing - I have source class definitions that are being stored in a Gist. Fetch the source and place in an existing cell - which implements the class into the notebook - renames the cell to the name of the class. Works great.

Right now I create all the cells needed to hold the classes by hand.
Was hoping could create them on the fly.

not that big of a deal. thx

It is possible to require the Gist directly, rather than copy-and-paste:

But you’d still need to create a cell for each class (each with the corresponding require) if you want them to be separate cells.

I’m just doing:
In the destination cell:

mutable Sample = ' '

The code in another cell has the line:

 mutable Sample = Function('return (' + classSourceFromGist + ')')();

It simple and works awesome.

Why mutable? This should work, too:

Sample = Function('return (' + classSourceFromGist + ')')()

TypeError: Assignment to constant variable Sample

btw - I’m not copy/pasting. It’s all automated.

Go to the third blue button. Just above you will see an error - that is because the class does not exist in the notebook yet. Press the button ExampleClass. Will see the magic happen.

You’ll have to delete the mutable Sample cell, too.

Did that and still get the type error - well, now Sample doesn’t have a reference.

Right, the snippet I posted is a top-level cell definition, not an assignment within a cell.

It took a while for

to work its way thru the cobwebs in my head. But it finally clicked. For me, that simple realization connected so many other “dots” in my understanding about how Observable cells work.

Would you agree that except maybe in very rare edge cases,

“there is no need to ever create an empty cell from another cell”

because no matter how you look at it… at top-level the cell always has to be defined. So might as well do that when you are writing the notebook.

Or am I still missing the boat?


I know there are as many ways out there to load gist source text into a cell and execute it as there are developers. Here is mine.

Sample = new SourceFromGist('8014cc196d580699feab787abc9398a0', 'sample class.js')

This snippet in another cell implements fetching the source

class SourceFromGist {
  constructor(gistid, filename) { return this.sourceFromGist(gistid,filename) }

  async sourceFromGist(gistid, filename, opts) {
    if (!(gistid && filename)) {return 'GistID and gist Filename is required to fetch code'}

    let gistRsp = await (await fetch(`https://api.github.com/gists/${gistid}`,opts)).json();
    return Function('return (' + gistRsp.files[filename].content + ')')();
  }
}

Yep, the ideal is each cell defines a value, and other cells may reference that value but don’t assign to (mutate) it.

I’ve updated my notebook to give an example of loading a Gist, too:

Ok! I’ll check-out your book. And, thanks a lot mike for your help.