guides-source icon indicating copy to clipboard operation
guides-source copied to clipboard

Document how to update arrays and objects in Ember Octane

Open ijlee2 opened this issue 3 years ago • 3 comments

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?
}

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?

ijlee2 avatar Sep 24 '20 16:09 ijlee2

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.

ijlee2 avatar Oct 09 '20 21:10 ijlee2

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).

gobijan avatar Oct 03 '22 22:10 gobijan

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.

dknutsen avatar Dec 13 '22 17:12 dknutsen