-
-
Notifications
You must be signed in to change notification settings - Fork 501
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
Replaces `this.get with ES5 getter where possible (#2303) in v3.2.0 #87
Conversation
@@ -66,7 +66,7 @@ import Component from '@ember/component'; | |||
export default Component.extend({ | |||
init() { | |||
this._super(...arguments); | |||
this.errors = []; | |||
this.set('errors', []); |
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.
This is a really good catch, thank you
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.
seconded 🎉
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 this looks good. I would like 1 more reviewer on this before we merge. The diff also needs to be applied to 3.3 after it's merged.
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.
Ok so this PR is amazing 😍 I was mostly scrolling down saying to myself "awesome... awesome!!! AWESEOME!!" 😂
My comments are in 3 categories mostly:
- tiny typos (I think there are only 2 of them)
- things that I don't fully understand
- things that have subtly changed the behaviour of the "defensiveness" of the code
This last point can be ignored if we don't think it's important/matters. Essentially in the "bad old days" doing something like this.get('something.you.want')
would not throw an error when something
or you
were null
or undefined
. I like to think of it as chain accessor protection.
Nowadays we will be seeing more crashes in JS because we're removing this automatic protection but the flip side is that we're getting closer to normal JavaScript behaviour 😂
Anyway, the only points that need to be fixed in this PR are the typos, everything else is opinion 👍
@@ -245,13 +245,13 @@ import { getOwner } from '@ember/application'; | |||
export default Component.extend({ | |||
audioService: computed('song.audioType', function() { | |||
let applicationInstance = getOwner(this); | |||
let audioType = this.get('song.audioType'); | |||
let audioType = this.song.audioType; |
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.
This is probably just a style thing but if you forget to pass song into play-audio it will throw an Exception here, whereas the old version would just return undefined
or null
or something 😂
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 don't know what the best way to communicate this would be 🤔 I personally still use get()
in cases like this but I import it from import { get } from '@ember/object'
and use it in the form: get(this, 'song.audioType')
Thoughts?
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 can see your point about the safeguard, and I'm often doing the same in Emberland. However, adopting more of the "newer" dot-notation syntax for getters, I would probably add an early return if (!this.song) return null;
in this particular case, since the core of this computed property requires a song
.
@@ -69,7 +69,7 @@ export default Component.extend({ | |||
|
|||
drop(event) { | |||
let id = event.dataTransfer.getData('text/data'); | |||
this.get('action')(id); | |||
this.action(id); |
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.
is this update potentially hiding the fact that action is now essentially just a variable name? I wonder if because it's a "thing" in Ember it might be worth updating it to be called dropAction()
instead?
This is potentially a super minor point so ignore if it's not important 😂
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'd second this. I could see myself getting confused by an action called "action"
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.
agree, will do.
@@ -66,7 +66,7 @@ import Component from '@ember/component'; | |||
export default Component.extend({ | |||
init() { | |||
this._super(...arguments); | |||
this.errors = []; | |||
this.set('errors', []); |
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.
seconded 🎉
@@ -190,7 +190,7 @@ export default PaymentMethod.extend({ | |||
linkedEmail: DS.attr(), | |||
|
|||
obfuscatedIdentifier: computed('linkedEmail', function () { | |||
let last5 = this.get('linkedEmail').split('').reverse().slice(0, 5).reverse().join(''); | |||
let last5 = this.linkedEmail.split('').reverse().slice(0, 5).reverse().join(''); |
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.
does this work with Models? I have in the back of my mind that you still need to use this.get()
for some things and I have a feeling that it has something to do with Ember Data but I don't know the specifics... Can anyone confirm?
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.
Will verify. ES5 getters can't be used for anything that implements a Proxy
and Ember Data is using them a lot.
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.
Verified that ES5 getters work on Ember Data Model attributes (as long as they are not relations). If it hasn't, this should probably be pointed out somewhere in the guides.
@@ -117,7 +117,7 @@ import EmberObject from '@ember/object'; | |||
|
|||
const Person = EmberObject.extend({ | |||
helloWorld() { | |||
alert(`Hi, my name is ${this.get('name')}`); | |||
alert(`Hi, my name is ${tthis.name}`); |
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.
double t
in tthis
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.
good catch!
@@ -152,7 +152,7 @@ import EmberObject from '@ember/object'; | |||
|
|||
const Person = EmberObject.extend({ | |||
init() { | |||
alert(`${this.get('name')}, reporting for duty!`); | |||
alert(`${tthis.name}, reporting for duty!`); |
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.
ttypo 😂
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.
Looks great! Most of my comments are about some additional small tweaks for simplification.
this.set('items', this.get('items').map((item) => { | ||
if (item.id === this.get('selectedItem.id')) { | ||
this.set('items', this.items.map((item) => { | ||
if (item.id === this.selectedItem.id) { |
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.
Unrelated to this PR, but it seems like this map()
is mutating the items. I think some kind of for…of or forEach could better express that we are changing the items in place. But no need to make the change in this PR unless you feel especially motivated to do so :-)
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 can look at it and propose a better example, no problem.
@@ -186,7 +186,7 @@ export default Component.extend({ | |||
}); | |||
``` | |||
|
|||
`this.get('onConfirm')` will return the function passed from the parent as the | |||
`this.onConfirm` will return the function passed from the parent as the | |||
value of `onConfirm`, and the following `()` will invoke the function. |
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 wonder if we still need the explanation about "the following ()". When "get()" was needed I did feel like I needed the explanation of the extra parens, but now it's just invoking a function property as usual.
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, agree, can tweak or remove that phrase.
@@ -25,7 +25,7 @@ export default Component.extend({ | |||
}, | |||
|
|||
titles: computed('todos.[]', function() { | |||
let todos = this.get('todos'); | |||
let todos = this.todos; |
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.
Could probably just inline this.todos
in the following line, unless you think there's extra clarity separating it out.
let firstName = this.get('firstName'); | ||
let lastName = this.get('lastName'); | ||
let firstName = this.firstName; | ||
let lastName = this.lastName; |
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'd probably in-line these into the template string instead of assigning to local variables
let firstName = this.get('firstName'); | ||
let lastName = this.get('lastName'); | ||
let firstName = this.firstName; | ||
let lastName = this.lastName; |
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.
Same as previous
@@ -15,7 +15,7 @@ export default Component.extend({ | |||
attributeBindings: ['style'], | |||
|
|||
style: computed('name', function() { | |||
const name = this.get('name'); | |||
const name = this.name; |
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.
Same as above
return this.get('store').query('rental', { city: param }); | ||
return this.get('store') | ||
return this.store.query('rental', { city: param }); | ||
return this.store |
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.
It might just be the formatting here on my phone, but I'm not even sure I understand what's happening in these lines. Is it two return statements in a row? The second one would never be reached, right? If so I think it'd be good to quickly clean it up as part of this PR.
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.
good catch, this needs to be fixed, will do.
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.
this is displayed as diff in the rendered version: https://guides.emberjs.com/release/tutorial/autocomplete-component/#toc_handling-results-coming-back-at-different-times
the redundant code makes sense here.
return this.get('store').findAll('rental'); | ||
return this.get('store') | ||
return this.store.findAll('rental'); | ||
return this.store |
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.
Same as above
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.
same, displayed as diff in the rendered guides.
guides/v3.2.0/tutorial/service.md
Outdated
@@ -196,14 +196,14 @@ export default Component.extend({ | |||
|
|||
didInsertElement() { | |||
this._super(...arguments); | |||
let location = this.get('location'); | |||
let mapElement = this.get('maps').getMapElement(location); | |||
let location = this.location; |
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.
this.location can probably be inlined in the following line
b28bf1d
to
e6a0737
Compare
e6a0737
to
71f0f4d
Compare
@jenweber @mansona @CodingItWrong I think I addressed all your feedback. Please let me know if there's anything else. Otherwise we could merge and I could apply the diff to 3.3. |
apply cspanring's getter work to 3.3 #87
Attempt to check off task 1 in emberjs/guides#2303
@jenweber please have a look and/or pull in more eyes to make sure the changes are OK.