can i swap out `import ... from` value, or does it have to be manually entered?

I’m working on a template that pulls values from a notebook. I call in each value from import for the notebook, and play it back out like this:

import {cookie, jar } from 'oBsCur3nMbrs'

then input these cells

cookie
jar

which wonderfully print out

chocolate
glass

Now, these are my data values / inputs - but I have values for 30 other people in other notebooks:

'1BsCur3nMbr'
'2BsCur3nMbrs'
'3BsCur3nMbrs'
'4BsCur3nMbrs'

...etc.

I tried to create another cell that names the notebook, populate it with values, and then to feed this value into an import statement (aiming if this worked to create a toggle between different notebooks’ values):

membervalue = '1BsCur3nMbr'
import {cookie, jar } from membervalue

… but it failed [SyntaxError: Unexpected token].

Is substitution of values into an import statement even possible? If so, how?

Import statements cannot contain dynamic values. You’d have to utilize your own Runtime instance to import notebooks dynamically.

… Luckily Mike has already done the heavy lifting :slight_smile:

1 Like

Thanks @mootari. I had caught that notebook when it came out and understood it to be an enhanced version of import ... with (which I recall you suggested somewhere has some potential flaws). I didn’t realize the dataflow would help in this context. Certainly I can now toggle out the values :slight_smile: thanks!

… Now I’m having trouble figuring out how to best manipulate these rendered cells. Currently I find it easiest to name and render them, then call the named cells into markdown [otherwise I’ve got some weird objects that I can get to play happily with md and html cells]. Still, this gets weird, as the rendered objects are first visible in their cells then dragged across the DOM and relocated in my markdown fields on selection:

Any tips for streamlining this?

EDIT: Sorry - I saw you typing as I kept changing the notebook and answer.

At least for initial, you get a promise that returns a generator that yields a promise, which makes it rather awkward when you have to inline the value:

md`${await importCell('initial', value).then(gen => gen.next().value)}`

You’ll probably want to write a wrapper function around importCell() that resolves a value completely before returning it.

With initial there is another problem: The return value is an HTML element, so you can only anchor it once into the DOM (the reason why it disappears from the initial cell).

To assign it to a reusable (i.e., consumable) value, I’d recommend one of these two approaches:

i = (await (await importCell('initial', value)).next().value).outerHTML
viewof i = Object.defineProperty(
  await (await importCell('initial', value)).next().value,
  'value',
  { get() { return this.outerHTML } }
)

You may also want to take a look at @j-f1’s fork:

https://observablehq.com/compare/cbe89acf8aadfc6d@136...d0bb058f650143a9@118

1 Like

Wow, this becomes rather complex rather quickly…

Thank you for your time and guidance in all of this!

You can simplify things by holding all imported values in a single cell. For example, if you change your select options to the full slug (e.g. "e695a608d52e208f" to "d/e695a608d52e208f") you can do the following:

// import Jed's fork
import {importNotebook} from 'd0bb058f650143a9'
// Fetch and expose all data at once
data = {
  const cells = ['initial', 'cookie', 'jar'];
  const nb = await importNotebook(value);
  return Promise.all(
    cells.map(name => nb.cell(name).next().value.then(v => [name, v]))
  ).then(Object.fromEntries);
}
1 Like