Load module that adds methods to the Array prototype

If I require a module that adds methods to the native Array prototype, cells that use the new methods throw an error because they don’t know to wait until the module has loaded. Is there a trick to get round this?

Thanks!

1 Like

Give the cell that loads the module a name, e.g. “extendArray”, and make sure to either use await in it or have it return a promise.
Then in your dependent cell simply write:

extendArray;

That way Observable will detect the dependency and wait for the parent cell to resolve.

I’ve created an example here: https://beta.observablehq.com/@mootari/load-module-that-adds-methods-to-the-array-prototype

Thanks for the reply and example.

I think this solution is fine for one or two cells. However, I am using the new methods in many cells so using a block and an explicit reference to extendArray each time seems rather clunky - not that I have any better ideas!

seems rather clunky

So seems modifying native prototypes. :wink: I don’t know what module you’re trying to use. But if it only provides utility functions for Array, chances are there’s an alternative (e.g. lodash).

Good point, but in this particular case I do need to modify the prototype. Perhaps your original suggestion is the only sensible way. I guess it comes down to the fact that I am just mutating an existing object which is not the Observable way.

Thanks for your help.

Thanks for asking this question — thinking about it over the weekend … there isn’t yet a satisfactory answer for you: Mutating values, and especially mutating global variables, isn’t the “Observable way”, and goes against the way our inter-cell dependency tracking tries to figure out the dependency graph of you code. Waiting at the top of each cell for extendArray to run, is indeed the way to do this.

But your use case is a good one for any kind of initialization code that needs to run before the notebook starts. We’ll think more about how Observable notebooks can better support these sorts of initialization cells.

3 Likes

Initialization may also solve another problem: Notebooks often take a few seconds to display meaningful content, especially if they require external dependencies that haven’t been cached or bundled yet (one of the reasons why I created https://beta.observablehq.com/@mootari/displaying-progress).
Initialization code could trigger a throbber or loading bar that displays until the notebook is ready to be viewed/interacted with.

I could imagine a function (available through the runtime?) that receives a promise and delays execution for all cells that are not part of the caller’s dependency tree. Cells with a dependency on that function would also be run before other cells. Once all active promises are resolved the progress display disappears and execution of the remaining cells continues.

I think that having the ability to run some initialization code would be great - in general and for my particular use case (I only want to mutate a global once before doing anything else).

I’m just poking around

if you do that:

Array = {
wait Promises.delay(1000)
const myArr = Array
myArr.prototype.tic = “tac_update_here_001”
return myArr
}

it’s throw ‘ReferenceError: Array is reserved’. But if you can than would throw circular dependence.

do would will literal notation wait for wrapped observable Array?

var tac = [].tic

What do you think? It’s similar to mootari but instead of creating eArray, you modify the caller with a lock