I was mocking up a component that has hooks into the didRender
and willDestroy
lifecycle but this.args
does not seem to be defined. My understanding is that @action
is what is required to bind the component context but it doesn’t seem to be working in this case. Any insight?
The component is intended to be used like:
<Block::ResizeAware @onResize={{ this.doSomeCalculations }} >
. . .
</Block::ResizeAware>
And the definition is something like:
import Component from '@ember/component';
import { action } from `@ember/object';
export default class BlockResizeAwareComponent extends Component {
@action handleResize() {
console.log("about to call passed in function...");
this.args.onResize();
}
didRender() {
super.didRender(...arguments);
this.handleResize();
}
}
This is currently resulting in a console error of:
Uncaught (in promise) TypeError: this.args is undefined
handleResize resize-aware.js:35
@ember/component
doesn’t have this.args
, only @glimmer/component
does.
Also note that, @glimmer/component
doesn’t have didRender
.
1 Like
Thank you. I’ve been building an ember app for a few weeks now and that never clicked until now. To summarize:
If import Component from '@glimmer/component'
use this.args
but if import Component from '@ember/component'
use @tracked value = something
?
Anyway, to close the loop, refactoring to something like this worked fine:
import Component from '@ember/component';
import { action } from '@ember/object';
import { tracked } from '@glimmer/tracking';
export default class BlockRenderAwareComponent extends Component {
@tracked onRender = null;
@action handleRender() {
console.log("about to call passed in function...");
this.onRender();
}
didRender() {
super.didRender(...arguments);
this.handleRender();
}
}
So @tracked
is just stating that a value will participate in the autotracking system, and this can happen with classic or glimmer components (or any other arbitrary class as it turns out). The difference in args is that with classic components the args were “mixed in” to the backing class properties which was a source of confusion. For glimmer components they’re specifically captured in this.args
.
I would strongly suggest not using classic components and instead use glimmer components going forward. Obviously that leaves the problem of the didRender hook. To handle that you could use ember-render-helpers or ember-render-modifiers, however that pattern is mostly discouraged. You could also write your own modifier and attach it to the tag or whatever.
2 Likes