# overcoming \`r is not iterable\` with new runtime? (or another mistake?)

**URL:** <https://talk.observablehq.com/t/overcoming-r-is-not-iterable-with-new-runtime-or-another-mistake/2729>\
**Category:** Help\
**Created:** [January 10, 2020, 12:08am UTC](https://talk.observablehq.com/t/overcoming-r-is-not-iterable-with-new-runtime-or-another-mistake/2729 "2020-01-10T00:08:39Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![aaronkyle](https://yyz2.discourse-cdn.com/flex030/user_avatar/talk.observablehq.com/aaronkyle/32/8106_2.png) [@aaronkyle](https://talk.observablehq.com/u/aaronkyle)\
**Post date:** [January 10, 2020, 12:08am UTC](https://talk.observablehq.com/t/overcoming-r-is-not-iterable-with-new-runtime-or-another-mistake/2729/1 "2020-01-10T00:08:39Z")

</div>

I have created a HTML file that imports a cell from my notebook following a pattern to call in specific cells that I believe I picked up from @fil somewhere along the way:

```auto
  for (let i in renders)
    renders[i] = document.querySelector(renders[i]);

```

This patterns works well when I view the HTML page locally on my computer and reference the notebook and runtime .js files from Observable, like this:

```auto
<script type="module">
      import {Inspector, Runtime} from "https://cdn.jsdelivr.net/npm/@observablehq/runtime@4/dist/runtime.js";
      import notebook from "https://api.observablehq.com/d/9aef18a2b092b886.js";

	  const renders = {
        "map": "#output",
      };

  for (let i in renders)
    renders[i] = document.querySelector(renders[i]);

  Runtime.load(notebook, (variable) => {
    if (renders[variable.name])
      return new Inspector(renders[variable.name]);
  });
    </script>

```

After downloading the tarball code and [uploading it to GitHub](https://aaronkyle.github.io/concept/data-visualization/sandbox/n/index_mod.html), I want to change the code to reference the local copy of the notebook .js file, like this:

```auto
import notebook from "./9aef18a2b092b886@429.js";

```

But doing so returns a console error:

```auto
Uncaught TypeError: r is not iterable
    at Function.value (runtime.js:2)
    at index_mod.html:28

```

I note that the approach I am using for calling in multiple cells doesn’t work when I add `?v=3` to the end of my notebook js code when pointing to the observable api, which leads me to expect that the code is only good for older versions of the runtime. Other forum discussions (referenced below) further lead me to believe this might have to do with changes to the runtime. Is that the case?

And what is the new pattern for calling in several specific cells? Would I just repeat this code block from [Jeremy’s primer on embedding](https://observablehq.com/@observablehq/downloading-and-embedding-notebooks):

```auto
new Runtime().module(notebook, name => {
  if (name === "chart") {
    return new Inspector(document.querySelector("#chart"));
  }
});

```

… Or is there a way that we can still, as before, define a list of target cells without repeating the code block several times?

Thanks in advance for your help and guidance!

* * *

Related reading:

- [Rendering imported cells](https://talk.observablehq.com/t/rendering-imported-cells/2455/5)
- [Embedding with Runtime.load seems to no longer load/reference dependencies](https://talk.observablehq.com/t/embedding-with-runtime-load-seems-to-no-longer-load-reference-dependencies/1617)

---

<div class="post-metadata">

**Author:** ![aaronkyle](https://yyz2.discourse-cdn.com/flex030/user_avatar/talk.observablehq.com/aaronkyle/32/8106_2.png) [@aaronkyle](https://talk.observablehq.com/u/aaronkyle)\
**Post date:** [January 10, 2020, 2:02am UTC](https://talk.observablehq.com/t/overcoming-r-is-not-iterable-with-new-runtime-or-another-mistake/2729/2 "2020-01-10T02:02:28Z")

</div>

[This thread](https://talk.observablehq.com/t/embedding-multiple-cells-from-notebook-into-a-react-app/2404/6) indicates that there may be no options but to repeat the new pattern. Copying in Jeremy’s response:

> [@Embedding multiple cells from notebook into a React App](https://talk.observablehq.com/t/embedding-multiple-cells-from-notebook-into-a-react-app/2404/6):
>
> … use a single runtime…:
> 
> ```auto
> import React, {Component} from "react";
> import {Runtime, Inspector} from "@observablehq/runtime";
> import notebook from "@kchalas/calendar-heatmap-too";
> class App extends Component {
> componentDidMount() {
> const runtime = new Runtime();
> runtime.module(notebook, name => {
> if (name === "viewof dataSelector") {
> return Inspector.into("#selector")()
> }
> if (name === "cal") {
> return Inspector.into("#ac-wrapper")();
> }
> });
> }
> render() {
> return (
> <div className="App"></div>
> );
> }
> }
> 
> export default App;
> 
> ```

As this code is written for a React app, it’s a bit hard for me to ascertain how to convert it back to Vanila js.

Here’s what I have working so far:

```auto
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
    <title>Embedded Observable notebook</title>
    <link href="https://unpkg.com/leaflet@1.2.0/dist/leaflet.css" rel="stylesheet">

  </head>
  <body>
  <div id="title"></div>
  <div id="map"></div>
<script type="module">
import {Runtime, Inspector} from "https://cdn.jsdelivr.net/npm/@observablehq/runtime@4/dist/runtime.js";
import define from "https://api.observablehq.com/d/9aef18a2b092b886.js?v=3";

const inspect1 = Inspector.into("#title");
(new Runtime).module(define, name => (name === "title") && inspect1());

const inspect2 = Inspector.into("#map");
(new Runtime).module(define, name => (name === "map") && inspect2());
  
</script>

```

… This approach still seems fairly labor intensive as compared to just defining a list of cells that one wishes to render out. Is there really no more elegant solution?

---

<div class="post-metadata">

**Author:** ![aaronkyle](https://yyz2.discourse-cdn.com/flex030/user_avatar/talk.observablehq.com/aaronkyle/32/8106_2.png) [@aaronkyle](https://talk.observablehq.com/u/aaronkyle)\
**Post date:** [January 10, 2020, 2:29am UTC](https://talk.observablehq.com/t/overcoming-r-is-not-iterable-with-new-runtime-or-another-mistake/2729/3 "2020-01-10T02:29:18Z")

</div>

Apparently this is it:

```auto
const inspect = Inspector.into("#title", "#map");
(new Runtime).module(define, name => (name === "title", "map") && inspect());

```

… Sorry, I am mostly just guessing and hacking away ☹ Inspiration to try this from @j-f1 's answer to : [DRY Leaflet layers & the HTML template literal](https://talk.observablehq.com/t/dry-leaflet-layers-the-html-template-literal/2727/2)

---

<div class="post-metadata">

**Author:** ![mootari](https://yyz2.discourse-cdn.com/flex030/user_avatar/talk.observablehq.com/mootari/32/581_2.png) [@mootari](https://talk.observablehq.com/u/mootari)\
**Post date:** [January 10, 2020, 1:24pm UTC](https://talk.observablehq.com/t/overcoming-r-is-not-iterable-with-new-runtime-or-another-mistake/2729/4 "2020-01-10T13:24:35Z")

</div>

It’s interesting to note that both Chrome and Firefox were unable to prettify the minified source of `runtime.js`:

- Chrome didn’t display any different formatting in the first place.
- Firefox did even worse, it produced invalid code where e.g. `for (const e of r)` became `for (const eofr)` (took me forever to figure out that’s not a thing).

---

<div class="post-metadata">

**Author:** ![jashkenas](https://yyz2.discourse-cdn.com/flex030/user_avatar/talk.observablehq.com/jashkenas/32/1778_2.png) [@jashkenas](https://talk.observablehq.com/u/jashkenas)\
**Post date:** [January 10, 2020, 6:53pm UTC](https://talk.observablehq.com/t/overcoming-r-is-not-iterable-with-new-runtime-or-another-mistake/2729/5 "2020-01-10T18:53:24Z")

</div>

I’ll try to explain a bit better … but if there’s anything that’s currently too confusing about [https://observablehq.com/@observablehq/downloading-and-embedding-notebooks](https://observablehq.com/@observablehq/downloading-and-embedding-notebooks), please let me know!

Creating a runtime:

```auto
new Runtime();

```

Loading a notebook into a new runtime:

```auto
new Runtime().module(notebook);

```

Loading a notebook into a new runtime, and attaching an observer to a single cell, named “chart”:

```auto
new Runtime().module(notebook, name => {
  if (name === "chart") {
    return new Inspector("#chart");
  }
});

```

The callback argument to `module` is invoked once for every named cell in the `notebook` definition, giving you a chance to set up an observer that renders to the DOM. In the previous example, we’re only rendering the cell named “chart” into an existing HTML element with the ID of “chart” … but in the following example, we’ll render “title” and “map” into `"#title"` and `"#map"`:

```auto
new Runtime().module(notebook, name => {
  if (name === "title") {
    return new Inspector("#title");
  } else if (name === "map") {
    return new Inspector("#map");
  }
});

```

Or more generically:

```auto
function renderNotebook(notebook, cellNames) {
  new Runtime().module(notebook, name => {
    if (cellNames.includes(name)) {
      return new Inspector(`#${name}`);
    }
  });
}

```

And then, to use it:

```auto
renderNotebook(notebook, ["title", "map"])

```

---

<div class="post-metadata">

**Author:** ![jipexu](https://yyz2.discourse-cdn.com/flex030/user_avatar/talk.observablehq.com/jipexu/32/1312_2.png) [@jipexu](https://talk.observablehq.com/u/jipexu)\
**Post date:** [January 11, 2020, 9:05am UTC](https://talk.observablehq.com/t/overcoming-r-is-not-iterable-with-new-runtime-or-another-mistake/2729/6 "2020-01-11T09:05:21Z")

</div>

i like and use the strategy proposed by @bgchen  
it’s work well !

```auto
const runtime = new Runtime();
const renders = {"charttitr": "#charttitr","chart": "#chart","aide":"#aide"};
   for (let i in renders)
      renders[i] = document.querySelector(renders[i]);
   const main = runtime.module(define, name => {
   if (renders[name])
      return new Inspector(renders[name]);
   else return true;
   })

```

---

<div class="post-metadata">

**Author:** ![aaronkyle](https://yyz2.discourse-cdn.com/flex030/user_avatar/talk.observablehq.com/aaronkyle/32/8106_2.png) [@aaronkyle](https://talk.observablehq.com/u/aaronkyle)\
**Post date:** [January 12, 2020, 12:41am UTC](https://talk.observablehq.com/t/overcoming-r-is-not-iterable-with-new-runtime-or-another-mistake/2729/7 "2020-01-12T00:41:56Z")

</div>

Thanks @jashkenas . This is helpful. I don’t suppose your notebook on embedding is confusing; rather - I remain confused about Javascript fundamentals (in this case, not intuiting that ‘[else if](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/if...else)’ would render both statements, rather than just stopping at the first truthy statement).

To close out this thread for others such as myself who are new and don’t immediately see such things, a minor revision to your solution: the addition of `document.querySelector`, without which the code you supplied will continue to return console errors.

Here’s the final code:

```auto
new Runtime().module(notebook, name => {
  if (name === "title") {
    return new Inspector(document.querySelector("#title"));
  }
  else if (name === "map") {
    return new Inspector(document.querySelector("#map"));
  }
});

```

-or-

```auto
function renderNotebook(notebook, cellNames) {
  new Runtime().module(notebook, name => {
    if (cellNames.includes(name)) {
      return new Inspector(document.querySelector(`#${name}`));
    }
  });
}

renderNotebook(notebook, ["title", "map"])

```

---

<div class="post-metadata">

**Author:** ![jashkenas](https://yyz2.discourse-cdn.com/flex030/user_avatar/talk.observablehq.com/jashkenas/32/1778_2.png) [@jashkenas](https://talk.observablehq.com/u/jashkenas)\
**Post date:** [January 12, 2020, 2:29am UTC](https://talk.observablehq.com/t/overcoming-r-is-not-iterable-with-new-runtime-or-another-mistake/2729/8 "2020-01-12T02:29:55Z")

</div>

> [@aaronkyle](#):
>
> a minor revision to your solution: the addition of `document.querySelector`

You’re right! I meant `Inspector.into()` instead of `new Inspector()`. Sorry!

> [@aaronkyle](#):
>
> I remain confused about Javascript fundamentals (in this case, not intuiting that ‘[else if](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/if...else)’ would render both statements, rather than just stopping at the first truthy statement).

The key here is that the callback is being called multiple times: once for every named cell defined in your notebook. You can add a `console.log(name)` to observe this happening. The `if ... else .. if` does indeed stop at the first truthy statement.
