Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUGFIX lts] Ensure {{each-in}} can iterate over keys with periods #18296

Merged

Conversation

pzuraq
Copy link
Contributor

@pzuraq pzuraq commented Aug 23, 2019

This PR refactors the iterator in each-in to use standard object get
notation for getting values instead of Ember.get. This should work
because:

  • All descriptors now install native getters
  • Object iterators use Object.keys to get the list of keys to iterate
  • unknownProperty is only ever triggered if a key is not in the
    object, which cannot be true if we just got the key using
    Object.keys. Thus unknownProperty will never be called for
    each-in.

This will allow users to use arbitrary keys for their objects, and
iterate over them with each-in. Keys will be tracked as if get were
used.

This PR refactors the iterator in `each-in` to use standard object get
notation for getting values instead of `Ember.get`. This should work
because:

* All descriptors now install native getters
* Object iterators use `Object.keys` to get the list of keys to iterate
* `unknownProperty` is only ever triggered if a key is not `in` the
  object, which cannot be true if we just got the key using
  `Object.keys`. Thus `unknownProperty` will never be called for
  `each-in`.

This will allow users to use arbitrary keys for their objects, and
iterate over them with `each-in`. Keys will be tracked as if `get` were
used.
@pzuraq
Copy link
Contributor Author

pzuraq commented Aug 23, 2019

Fixes #17529

@rwjblue rwjblue merged commit 6fb17f5 into master Aug 23, 2019
@delete-merged-branch delete-merged-branch bot deleted the bugfix/ensure-each-in-can-iterate-over-arbitrary-keys branch August 23, 2019 14:36
value = obj[key];

// Add the tag of the returned value if it is an array, since arrays
// should always cause updates if they are consumed and then changed
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is that right? If you pass this to, e.g. #each, we handle this there already. If you just pass the value to, say, a component or a helper, I am not sure we need to invalidate those if the content of the array changes?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the test you added should pass without consuming [].

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is part of autotracking as a whole, it allows consumers to use arrays (both native and non-native) anywhere they consume a tracked value, and have mutations to that array be autotracked. In practice, this is like the native getters migration, it’ll mean users can access any array as if it were a normal, native array. They only need to use methods for updating the state of the array (we need native Proxy to allow them to update with native syntax).

Even when we do get to native Proxy though, this will allow us to omit a get handler in the Proxy, which should help us avoid perf issues with proxies

let value: any;
let key = keys[i];

value = obj[key];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This breaks when obj is a proxy, is that okay?

In general, if the solution requires avoiding get semantics, I think that is not okay. However, maybe in this case it is fine since we already did Object.keys above so it won't trigger unknownProperty anyway.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct, I started writing the code to do unknownProperty and realized that by definition, it could never run, which is why I omitted it.

backspace added a commit to backspace/prison-rideshare-ui that referenced this pull request Nov 7, 2019
This was fixed in emberjs/ember.js#18296 but I can’t bear
to update Ember at the moment. This is untested code 😳
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants