Unidirectional Glimmer?

In Glimmer Component, the data flow should be unidirectional right? I’m passing an array from controller to the component, I am accessing the array with this.args and I could mutate it using pushObject in component. It is not freezed. Am I missing something?

1 Like

The references are one-way. As in, if your controller passes <TheComponent @array={{this.array}}, and TheComponent tries to do this.args.array = somethingElse, it won’t work.

But we don’t try to control deep object mutation automatically. Preventing it entirely in Javascript is pretty expensive and error prone. If we actually called Object.freeze on your array, then you couldn’t mutate it even in the original controller. If we copy it first and then freeze it, we’re doubling the memory consumption. If the array has more objects in it, which have more object and arrays in them, we’d need to recurse down into all of those and repeat the process to really freeze the whole thing.

It’s just not a thing that’s good to force onto Javascript.

If you want an immutable data structure, you can do that by explicitly creating an immutable data structure. One example would be the List from Immutable.js. Another would be to try Immer.


Note that there is currently an interop problem with Immer and @tracked in Ember; see this issue for details. This specifically affects Ember, whether using classic or Glimmer components; Glimmer.js doesn’t have this issue. Hopefully that’ll be resolved soon, as it causes a variety of different issues, not just for Immer.