guides-source
guides-source copied to clipboard
Document how to update arrays and objects in Ember Octane
Background
Description
We currently don't describe well how to update tracked arrays and objects in Ember Octane. On Discord, now and then, a developer does ask how they can do so.
@tracked myArray = [];
@tracked myObject = {};
@action updateMyArray() {
// How?
}
@action updateMyObject() {
// How?
}
- In-Depth Topics - Autotracking In-Depth - Plain Old JavaScript Objects (POJOs)
- In-Depth Topics - Autotracking In-Depth - Arrays
- Upgrading - Tracked Properties - Plain Old JavaScript Objects (POJOs)
- Upgrading - Tracked Properties - Arrays
Possible TODOs
1. Arrays
- [ ] Create an example (the example may need to depend on the surrounding page context)
- [ ] Explain that Ember does not react to
this.myArray.push(...);
. - [ ] Explain possible solutions
- immutable approach
-
EmberArray
-
tracked-built-ins
2. Objects
- [ ] Create an example (the example may need to depend on the surrounding page context)
- [ ] Explain that Ember does not react to
this.myObject.myProperty = ...;
. - [ ] Explain possible solutions
- immutable approach
- native class
-
tracked-built-ins
3. Backport
Once the changes are approved for release
directory, backport the changes all the way back to Ember 3.15.
Questions
- We have 2 pages (Autotracking In-Depth & Tracked Properties) with almost similar content. Can one page refer to another?
Sorry the details are a bit fuzzy. Please feel free to reach out to me for questions about what to write.
For Hacktoberfest, I think we can split this issue into 2 (one for arrays, and another for objects), to keep the scope small.
Hi I just stumbled upon this.
I tried some approaches and what worked best for me was the replace method:\
let match = this.todos.find((todo) => todo.id === receivedTodo.id);
let index = this.todos.indexOf(match);
this.todos.replace(index, 1, [receivedTodo]);
I had no luck with Object.assign:
Object.assign(match, receivedTodo);
Changes here were not propagated to my view (@tracked collection).
I know I'm just randomly weighing in here but having just taken a good look at the docs on autotracking while working on onboarding materials for my team it's fresh on my mind. So my unasked-for 2 cents:
I think part of the reason there isn't a clear direction to take these docs in is that it's very dependent on context. The three basic buckets I've seen complex-tracking solutions fall into are the following:
- replacement (i assume we're referring to this method when we say "immutable" approach?)
- pros: simple, clear and readable, "just Javascript"
- problems: possible performance issues, weird (not clear why you're replacing the object or setting it to itself)
- custom class with tracked properties (if the properties are known)
- pros: clear and understandable, may be good abstraction anyway, "just Javascript"
- problems: not one size fits all (overkill for simple cases, doesn't work where size/keys/properties are unknown/dynamic)
- tracked-built-ins (if the properties/keys/size need to be dynamic)
- pros: easy, works for any situation, performant*
- problems: not built in (but will be very soon), not "just Javascript", overkill for simple cases
I don't think we should ever recommend using EmberArray/Ember.A (which seems to be what we do now). I think that will just lead to confusion and long-term churn.
I know the general idea is to point people in the simplest direction in the guides but that's more difficult here. I suppose the replacement/immutable method would work best for the basic Tracked Properties page, and the other options (and what scenarios they are best for) could be covered on the in-depth topics page. But IMO they should all be covered and it's important to call out when/why you might want to use each one. I think this is an important topic that anyone can get hung up on.
Two recent RFCs have slightly clarified the direction this should probably take: https://github.com/emberjs/rfcs/pull/812 - merged, add tracked-built-ins to the framework https://github.com/emberjs/rfcs/pull/864 - proposed, deprecated Ember.A
So I don't think it makes sense to ever recommend EmberArray as a solution to this, and I think it will be ok to build the guides around tracked-built-ins (at least once they land) since they will actually be built-in.
Anyway that's my two cents. Happy to contribute to these pages if there's enough consensus on what direction to go here.