-
Notifications
You must be signed in to change notification settings - Fork 1
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
Don't require get
/unwrap
when working with config
and objects in the environment
#58
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🥳
assert.strictEqual(get(this.config, 'baz'), 'bar'); | ||
|
||
set(this.env, 'foo', 'qux'); | ||
assert.strictEqual(get(this.config, 'baz'), 'qux'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think .get
s on the config object should be able to be removed now
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep! These tests were largely lifted whole-cloth from the other existing ones, just having the boilerplate refactored. My plan is to come through and get rid of all the get
calls in the next PR where I clean up the Environment
portion of things—then I won't have to comb through and think so hard about which get
s are necessary and which aren't, I'll be able to just drop them all.
const subvalue = get(value, 'key'); | ||
assert.strictEqual(get(subvalue, 'child'), 'bar'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are these .get
s still necessary for subvalues? Same question for the "array values" test below.
assert.strictEqual(get(ext2, 'a'), 'newbar'); | ||
assert.strictEqual(get(ext2, 'b'), undefined); | ||
|
||
// Writing to an inherited key updates at the level it was inherited from |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These are interesting. Can you explain when/why the environment is extended like this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see now - it's done in components that render nested exclaim configuration.
Background
Today, the
config
that every Exclaim component receives, as well as any object retrieved from the Exclaim environment, is wrapped in anEnvironmentArray
orEnvironmentData
shell that requires all properties are accessed viaget
, and wraps any returned values from that get in further shells.When Exclaim was first built, all computed properties in Ember required
get
/set
, so it wasn't really a big deal that our strategy for handling binding resolution required everything to go through those, since it just felt like any other normal Ember code. Today, though, with computed properties setting up native getters, and the distinction between wrapped and unwrapped data causing chaos with TS, being forced to useget
everywhere and know when tounwrap
things feels much worse and is a lot more confusing.This Change
This change completely overhauls how we manage
$bind
and$helper
in UI specs. Previously, when you calledget
on a field for the first time, if we discovered aBinding
orHelperSpec
in the underlying data, we would create a computed property on the fly for it and thenget
that. If we discovered any other non-primitive value, we would create a computed that returned that value wrapped inEnvironmentData
so that it too would have this just-in-time computed installation set up.This approach required the consumer call
get
to act as an intermediary and give us the opportunity to do that setup, so even after normal computeds stopped requiringget
, it was still required for Exclaim objects.With this change, we instead crawl the config once and set up the appropriate computed properties immediately, which means since the computeds themselves don't require
get
, and since we don't need to do anything special for nested values, we can stop wrapping everything as well.Not This Change
There are a few notable things this change does not do:
Environment
to not requireget
. The@env
arg that components receive is kind of a weird hybrid of "pretends to be the@env
arg that was passed toExclaimUi
" while also being "a grab bag of tools for managing the scope that$bind
sees, and also weirdmetaForField
stuff". To avoid this PR becoming overwhelming, I refrained from reworking that here, but I intend to take a pass at that as well before declaring 2.0.metaForField
/resolveEnvMeta
. After surveying our current usage, I think we should do that and replace it with a simpleresolveEnvPath
importable, which is the only real use case we ever actually had for field metadata. Likely makes sense as part of the environment changes mentioned above.@ember/component
,@computed
, etc)ExclaimUi
that uses unadorned getters for binding instead ofcomputed()
for compatibility with@tracked
data. That may or may not happen before 2.0, but the idea would be that this opt-in mode becomes the only mode in 3.0 and acts as a path to incremental migration to@tracked
in 2.x.