-
-
Notifications
You must be signed in to change notification settings - Fork 407
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
Deprecate getWithDefault #554
Conversation
I'm a fan. This is codemodable. 👍 |
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.
Should EmberObject.getWithDefaultalso be deprecated?
if (result === undefined) { | ||
result = defaultValue; | ||
} | ||
``` |
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.
let result = get(obj, 'some.key') || defaultValue;
Is this an alternative option? Also, should the codemod require get
or can we use plain property accessors?
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 it makes sense to use get
to minimize behaviour differences
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.
Codemodding paths and interpolated paths will be significantly harder as well:
getWithDefault(obj, 'foo.bar');
getWithDefault(obj, `foo.${key}`);
getWithDefault(obj, path);
I'd also suggest to codemod towards get
and then potentially run another codemod from get
towards native accessors in the future.
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.
FWIW, there is already a codemod for get()
to native: https://github.com/ember-codemods/es5-getter-ember-codemod. (at least for simple properties, no paths yet)
And someone even suggested covering getWithDefault()
already: ember-codemods/es5-getter-ember-codemod#1 😝
Co-Authored-By: Thomas Wang <[email protected]>
Co-Authored-By: Thomas Wang <[email protected]>
Thanks for working on this @chrisrng! Seems like a good idea to me... |
Explicitly say both function and class methods are being deprecated
I don't think to have a code mod to do the following is really useful.
I would suspect most people would modify the code mod to use their own util or use something like lodash (if they want that default behavior). Cause having one line turn into 4 while also increasing the complexity is not something I would think people would want in their code |
FYI @steventsao added this to eslint-plugin-ember ember-cli/eslint-plugin-ember#594 |
Yeah turning one assignment into a block would not be ideal. But this can be a one-liner, right? // I imagine the value of `get()` is cached
const result = get(obj, 'some.key') === undefined ? get(obj, 'some.key') || defaultValue; Optional chaining and nullish coalescing: const result = obj.some?.key ?? defaultValue; |
@steventsao @EWhite613 Codemodding it in the safest way possible is the important bit here. You can definitely do it with a ternary, and that's fine with me as well. I suggested this particular output to @chrisrng because it seemed the clearest to me; a ternary would also be fine but does impose the slight extra cognitive overhead of having to think about the caching question when you're reading it. I'm not married to the |
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.
We discussed this in the Ember core team meeting today, and the team is broadly in favor of moving forward here. I think we need a few (hopefully minor) tweaks here.
We will likely need to at least mention nullish coalescing in the transition path, but also need to properly balance that against both the differences in getWithDefault
's behavior (only uses undefined
instead of null
+ undefined
) and how destructuring with assignment would work (which uses "falsey" rules.
@chrisrng - Concretely, would you mind taking a crack at tweaking the transition path section to incorporate some messaging about destructuring, as well as some examples using nullish coalescing (basically explaining that there is a difference between it and getWithDefault
, but if a particular case didn't care about the difference how it would look) and destructuring with defaults (same basic caveat, destructing with default uses "falsey" semantics).
Co-Authored-By: Robert Jackson <[email protected]>
Co-Authored-By: Robert Jackson <[email protected]>
Thanks to @johncowen for pointing out that this is on the way to being deprecated: #5944 (comment) emberjs/rfcs#554
|
||
The problem with `getWithDefault` is that its behaviour is confusing to Ember developers. The API will only return the default value when the value of the property retrieved is `undefined`. This behaviour is often overlooked when using the function where a developer might expect that `null` or other _falsy_ values will also return the default value. | ||
|
||
Given the JavaScript language will soon (currently in Stage 3) give us the appropriate tool for this use case using the [Nullish Coalescing Operator `??`](https://github.com/tc39/proposal-nullish-coalescing), we can deprecate usage of `getWithDefault` and use that instead. |
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.
Some text should be added here: Ember can only suggest nullish coalescing syntax once Ember CLI supports that syntax out of the box. It should be supported in a stable release of Babel, but additionally we need to be sure that ember new
includes that version of Babel.
And the deprecation instructions should explain how to get the proper version installed.
We discussed this in todays core team meeting and have decided to move this into final comment period. |
fyi adding codemod https://github.com/steventsao/ember-no-get-with-default-codemod |
Rendered