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

Improve the error message when this is undefined #17

Open
jenweber opened this issue Nov 8, 2019 · 8 comments
Open

Improve the error message when this is undefined #17

jenweber opened this issue Nov 8, 2019 · 8 comments

Comments

@jenweber
Copy link

jenweber commented Nov 8, 2019

If you try to use this within methods called by {{on}} and {{fn}}, they show a helpful error instructing the developer to use the @action decorator. The render modifiers could show something like that too.

Here's an example "error" use case for did-insert:

<div class="my-container" {{did-insert this.renderEditor}}></div>
import Component from '@glimmer/component';

export default class CodeEditor extends Component {
  renderEditor(el) {
    console.log(this.args.code)
  }
}

TypeError: this is undefined

{{fn}} uses this error message:

You accessed this.arg2 from a function passed to the fn helper, but the function itself was not bound to a valid this context. Consider updating to usage of @action.

@jenweber
Copy link
Author

jenweber commented Nov 8, 2019

cc @rwjblue this was opened at your suggestion following some chat in octane-migration.

@ELepolt
Copy link

ELepolt commented Dec 20, 2019

Hey all. Just came upon this today. Is there a more proper way to access this inside of a component?

// component.hbs
<Input @type="text" @value={{@token}} {{did-insert this.verifyToken @token}}/>

// component.js
verifyToken(token) {
  console.log(this) // logs 'undefined'
}

Am I misinterpreting how this addon should be used?

@dgavey
Copy link

dgavey commented Jan 2, 2020

@ELepolt You have to use the @action decorator for your this.verifyToken function in the component class or else this === undefined

Example

@action
verifyToken(token) {
  console.log(this) //Works
} ```

@ELepolt
Copy link

ELepolt commented Jan 2, 2020

#OctaneWoes. Thank you so much.

@tniezurawski
Copy link

One thing that I've learned here that someone can make use of is this.set() a value. Even with @action I've got an error: TypeError: this.set is not a function.

In my case, I had to save a reference to a node and solved that by using set from @ember/object:

{{!-- template.hbs --}}

<div {{did-insert this.setFileRef}}>
  <div id="selector"></div>
</div>
// component.js

import Component from '@glimmer/component';
- import { action } from '@ember/object';
+ import { action, set } from '@ember/object';

export default class SomeComponent extends Component {
  @action
  setFileRef() {
-    this.set('fieldRef', document.querySelector('#selector'));
+    set(this, 'fieldRef', document.querySelector('#selector'));
  }
}

That might not be the best example because in this case {{ref}} in nicer. But I'll leave it here anyway.

@dgavey
Copy link

dgavey commented Jan 15, 2020

@tniezurawski You don't need to use set in a glimmer component, in fact it's not recommended.

Also, you can do this code differently here. As a modifier passes in the element it's attached to so instead of looking through the whole document you can look just within this component.

@action
  setFileRef(element) {
    this.fieldRef =  element.querySelector('#selector'));
  }

@tniezurawski
Copy link

@dgavey Oh, nice! Thanks for the explanation!

@mcfiredrill
Copy link

Anyone have a hint on where I could go about adding this ?
Maybe here? https://github.com/emberjs/ember-render-modifiers/blob/master/addon/modifiers/did-insert.js#L61
How could I check that it's an action and not a regular function?

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

No branches or pull requests

5 participants