Hello fellow Observable users,
I’ve a simple notebook here here which allows a point (blue) to be dragged and which has handlers for drag start, dragging and drag ended. All works fine until I add a viewof to update the variable coeffs, at which point only drag start seems to work. I can’t understand the interaction but am still very much a beginner so appreciate (and hope) it may be something obvious I have done.
Thanks for any advice,
The problem, in a nutshell, is mutation across cells: your current notebook relies on mutating values implicitly defined by other cells. Whenever possible, you want to avoid mutation across cells in Observable because it makes it harder to understand dataflow, as when you click the “New polynomial” button to change the value of coeffs.
The corresponding fix to fold any cell that mutates another cell’s value into that other cell. So, updatePoints should be folded into the chart cell, and so should drag (since it calls updatePoints).
Here’s the fix applied to your notebook, and you click Merge if you like:
Here’s a relevant passage from the recent Learn D3 tutorial:
A subtle consideration when working with data in Observable is whether to put code in a single cell or separate cells. A good rule of thumb is that a cell should either define a named value to be referenced by other cells (such as data above), or it should display something informative to the reader (such as this prose, the chart above, or cells which inspect the data).
A critical implication of this rule is that you should avoid implicit dependencies between cells: only depend on what you can name.
Why? A notebook’s dataflow is built from its cell references. If a cell doesn’t have a name, it cannot be referenced and cells that implicitly depend on its effect may run before it. (Cells run in topological order, not top-to-bottom.) Implicit dependencies lead to nondeterministic behavior during development, and possible errors when the notebook is reloaded!
For example, if one cell defines an array and a second cell modifies it in-place, other cells may see the array before or after the mutation. To avoid this nondeterminism, make the dependency explicit by giving the second cell a name and copying the array using Array.from or array.map. Or combine the two cells so that only the already-modified array is visible to other cells.
Thank you so much Mike: this is so helpful and clears up my confusion. I will be certain to read the tutorial to help me understand this wonderful tool.