Does mutable work with Objects?

I tried to use the (new?) mutable keyword, however it’s unclear to me whether they work with objects? I.e. I would have expected the following notebook to work?

48%20PM

Re-evaluating any of the obj.foo cells will show the correct value

1 Like

mutable works with any value — but I’m afraid that it’s not a magic keyword … it doesn’t know when you later mutate the properties of any shared object, array, or other value.

What you’re looking for is:

{
  await Promises.delay(1000);
  mutable obj = {foo: "bar"};
}

Which is to say: you assign a new value to mutable obj. Does that make sense?

Totally does, mutable refers to assignment of the variable, not to mutating the value itself. Got it!

Will obj.foo = 'bar'; mutable obj = mutable obj or the like trigger an update without creating a new object from scratch?

Edit: seems so, https://beta.observablehq.com/@jrus/mutable-test

What I don’t understand is why the “reset” button on that page doesn’t cause the update_obj cell to reevaluate, but pressing the “run” arrow on the top obj cell does.

The update_obj cell only references mutable obj, not obj, and so is not re-run when obj changes.

Also, the mutable operator only tracks shallow mutability (assignments to mutable.value), not deep changes to an object. Setting obj.foo will modify the obj object internally, but cells that reference obj won’t be re-run until you assign a value to mutable obj, even if the new value is the same as the old value.

Even with the mutable operator, it’s still a good practice to use immutable values whenever possible. Meaning, instead of this:

{
  mutable obj.foo = "bar";
  mutable obj = mutable obj;
}

Say:

{ mutable obj = {foo: "bar"}; }

Or, if you want to be fancy and only change obj.foo:

{ mutable obj = {...mutable obj, foo: "bar"}; }

Or, without spread syntax (for Safari):

{ mutable obj = Object.assign({}, mutable obj, {foo: "bar"}); }
1 Like

Thanks - this helps clarify something that I was tripping over the other day.

That is awesome @mbostock, that was totally what I was looking for to get my ML colour prediction notebook working in an observable way.

1 Like