Stencil: Not possible to expose a getter with @Method

Created on 8 Oct 2017  ·  7Comments  ·  Source: ionic-team/stencil

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:

  1. git clone [email protected]:mortenson/stencil-getter.git
  2. cd stencil-getter && npm install && npm start

See 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

bug

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.

All 7 comments

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 )

  • use props as only source of truth, consumers of your component will thank you later ;)

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

Was this page helpful?
0 / 5 - 0 ratings

Related issues

MatanYadaev picture MatanYadaev  ·  3Comments

romulocintra picture romulocintra  ·  3Comments

kensodemann picture kensodemann  ·  3Comments

MrMcGibblets picture MrMcGibblets  ·  3Comments

ryanmunger picture ryanmunger  ·  3Comments