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

Replaces `this.get with ES5 getter where possible (#2303) in v3.2.0 #87

Merged
merged 1 commit into from
Jul 29, 2018

Conversation

cspanring
Copy link
Contributor

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.

@@ -66,7 +66,7 @@ import Component from '@ember/component';
export default Component.extend({
init() {
this._super(...arguments);
this.errors = [];
this.set('errors', []);
Copy link
Contributor

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

Copy link
Member

Choose a reason for hiding this comment

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

seconded 🎉

Copy link
Contributor

@jenweber jenweber left a 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.

Copy link
Member

@mansona mansona left a 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;
Copy link
Member

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 😂

Copy link
Member

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?

Copy link
Contributor Author

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);
Copy link
Member

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 😂

Copy link
Contributor

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"

Copy link
Contributor Author

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', []);
Copy link
Member

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('');
Copy link
Member

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?

Copy link
Contributor Author

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.

Copy link
Contributor Author

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}`);
Copy link
Member

Choose a reason for hiding this comment

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

double t in tthis

Copy link
Contributor Author

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!`);
Copy link
Member

Choose a reason for hiding this comment

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

ttypo 😂

Copy link
Contributor

@CodingItWrong CodingItWrong left a 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) {
Copy link
Contributor

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

Copy link
Contributor Author

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.
Copy link
Contributor

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.

Copy link
Contributor Author

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;
Copy link
Contributor

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;
Copy link
Contributor

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;
Copy link
Contributor

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;
Copy link
Contributor

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
Copy link
Contributor

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.

Copy link
Contributor Author

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.

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 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
Copy link
Contributor

Choose a reason for hiding this comment

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

Same as above

Copy link
Contributor Author

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.

@@ -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;
Copy link
Contributor

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

@cspanring
Copy link
Contributor Author

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

@jenweber jenweber merged commit 6364485 into ember-learn:master Jul 29, 2018
acorncom added a commit that referenced this pull request Jul 30, 2018
apply cspanring's getter work to 3.3 #87
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants