Resources:
Before submitting an issue, please consult our docs.
Stencil version: (run npm list @stencil/core from a terminal/cmd prompt and paste output below):
$ npm list @stencil/core
[email protected] /Users/samuelmortenson/repos/stencil-getter
└── @stencil/[email protected]
I'm submitting a ... (check one with "x")
[x] bug report
[ ] feature request
[ ] support request => Please do not submit support requests here, use one of these channels: https://forum.ionicframework.com/ or https://stencil-worldwide.slack.com
Current behavior:
If you add a @Method to a component and use the get keyword in front of the function name, the component will compile incorrectly leading to a Uncaught ReferenceError: Method is not defined error when loaded in a web browser.
Expected behavior:
I would expect that Stencil elements could expose getter/setter methods using @Method. These accessors are super useful, especially when trying to emulate the behavior of something like the <input> element's "value" attribute. It can get set as an initial property, and the attribute never changes in the DOM, but when input.value is called the current value is returned. Would be great to do something similar in Stencil.
Steps to reproduce:
git clone [email protected]:mortenson/stencil-getter.gitcd stencil-getter && npm install && npm startSee Uncaught ReferenceError: Method is not defined in your web browser.
Related code:
Here's the syntax I would expect to expose a getter/setter:
@Method()
get value() {
return Math.random();
}
(ref https://github.com/mortenson/stencil-getter/blob/master/src/components/my-name/my-name.tsx#L12)
Other information:
Here's the TypeScript documentation on Accessors (get/set): https://www.typescriptlang.org/docs/handbook/classes.html#accessors
you should use @Prop for this
@Prop()
get value() {
return Math.random();
}
although note, that if you'll set the property, the getter won't work anymore
Overall exposing methods as Component API is antipattern ( Ionic guys provided this API probably for legacy reasons and easier ionic migration )
@Hotell Using @Prop allowed my component to load without errors, but the return of document.body.getElementsByTagName('my-name')[0].value never changes, even if the property isn't initially set.
I think that the input element is a good example of how this can be implemented without things getting out of hand. If you call input.value that gets the current value of the element, but input.getAttribute('value') returns the initial property value, not the current value. The initial value isn't mutable, but the value getter represents some internal state of the component.
All that said, even if Stencil fixed the compile error, you can't have a @Prop and a @Method with the same name, so we would another follow up issue to emulate the input element's behavior.
Using @Prop allowed my component to load without errors, but the return of document.body.getElementsByTagName('my-name')[0].value never changes, even if the property isn't initially set.
yeah that's right
I think that the input element is a good example of how this can be implemented without things getting out of hand. If you call input.value that gets the current value of the element, but input.getAttribute('value') returns the initial property value, not the current value. The initial value isn't mutable, but the value getter represents some internal state of the component.
Overall using attributes is antipattern ( it's slow, it's always string, coercion logic is needed...)
It would be nice though to be able to configure this behaviour within Prop decorator ( we allow granular configuration in @skatejs for instance )
Only use case where attribute reflection/setting via attributes makes sense is for styling purposes [checked]:{} etc
I think getter / setter does not works with Stencil, because of this has decorators like @PropWillChange and @PropDidChange
right. that's kinda the downside of "the compiler", you cannot use javascript as you normally would, you're tightly coupled to Stencil API/syntax@Prop*Change hooks are definitely the "right" way in this case
Great point! I'm not seeing any reason why the getter shouldn't work. I think this could get fixed and WillChange or DidChange wouldn't be needed.
Hello all! Closing this for now as we plan to re-evaluate this later. Thanks for using Stencil!
Most helpful comment
Great point! I'm not seeing any reason why the getter shouldn't work. I think this could get fixed and WillChange or DidChange wouldn't be needed.