What is dif between Observable cells and explicitly making a cell a generator function?

I have a notebook where things work when I use standard Observable ( thing = {} ) and yield my SVG nodes before calling a function that needs them to do getBoundingClientRect on the results.

thing = { 
    const svgNode = svg'<svg width=${layout.width} height=500 id='comms'></svg>';
    // Do SVG stuff
    yield svgNode;
    renderStuffThatNeeds_getBoundingClientRect();
    }

I prefer calling the cell as a function because then I get a named line in Obs that I can find when that results of that cell are rendered in another cell via ${thing()} so I tried making it a function…

If I try to turn the cell into a function ( function thing() {} ) I get the “yield is a reserved word” error because the cell isn’t a generator.

If I try to turn the cell into a generator ( function* thing() {} ) the function after the yield fails with “TypeError: Cannot read properties of null (reading ‘getBoundingClientRect’)”

How is an Observable cell as a generator different than explicitly making a cell a function* ?

The difference is that when a cell yields (or returns) a value, the Observable inspector will insert that element into the DOM for you. Whereas if you have a local variable (such as the result of calling a generator function), it won’t be inserted into the DOM unless you do it yourself. So this…

{
  for (let i = 0; i < 10; ++i) {
    yield htl.html`hello ${i}`;
  }
}

Is the same as this:

function* hellos() {
  for (let i = 0; i < 10; ++i) {
    yield htl.html`hello ${i}`;
  }
}
{
  for (const hello of hellos()) {
    yield hello;
  }
}

Is the same as this…

yield* hellos()

Is the same as this…

hellos()

If you want to use getBoundingClientRect, you must ensure that the DOM element has been added to the DOM first. You can do this implicitly by requiring that it has been yielded or returned as a cell value, or you can do it explicitly by adding it to the document.body (and then perhaps removing it after calling getBoundingClientRect).

Or, if you can avoid using getBoundingClientRect, then you don’t have to worry about whether the DOM element is connected or not.