Stencil version:
@stencil/[email protected]
I'm submitting a:
Current behavior:
Compiler error: ReferenceError: SOME_EVENT is not defined at eval
Expected behavior:
Should compile using the variable's value as the event name.
Related code:
import { Component, Event, EventEmitter } from '@stencil/core';
/** Could also be a string variable imported from another file */
const SOME_EVENT = 'some-event';
@Component({
tag: 'my-component',
styleUrl: 'my-component.scss',
shadow: true
})
export class MyComponent {
@Event({eventName: SOME_EVENT})
private someEvent:EventEmitter;
protected componentDidLoad(){
this.someEvent.emit(this);
}
render() {
return <slot />;
}
}
Other information:
This same bug affects nearly any configurable aspect of stencil decorators if a variable is used in place of a string. Multiple components may reference the same value and it would be preferable to write that primitive value in a single place to simplify refactoring and avoid typo errors (the bane of JS debugging).
Currently the compiler is looking for String Literals within the decorators. I think you have a valid use case for why variables should be allowed. We will leave this open as a bug and will add to our roadmap. For now I would recommend using string literals.
Unfortunately I was unable to find a way to make this work with static analysis. I will be closing this issue as a won't fix.
@jthoms1 Some update about this? It's quite limiting. I'm building a UI Library using Stencil as core and consumed by React and Angular. The problem is that I want to make two different builds: one for standard web components (using Shadow DOM) and another withour Shadow DOM for using in both frameworks. I can't do this because this issue.
Ideas? Thanks in advance.
Hi @jthoms1. It would be helpful for me too to use variables inside decorators. we build a stencil app. but in the future, we might build another app with react or something else, and consume just the components from the app. therefore, we are doing all inter-component communication with events. therefore i want to use the @Event decorator and pass the eventName as variable, so that we can share eventNames between components. Do you think it would be possible to reopen this issue and talk again about it?
Thank you very much in advance
@jthoms1 a decorator is just syntactic sugar for a function that runs at a given lifecycle in a class (which is also just syntactic sugar for a constructor fundtion). A function that accepts a variable as an argument is as basic as it gets in JavaScript. This is definitely a bug, and one that should be fixed. Static analysis be damned if we can't pass a variable to a function.
I agree with @pr3tori4n and others that this is worth the effort to fix.
Meanwhile...
@Listen(Reporting.EVENT_REPORT_CHANGED, { target: 'document' })
async reportChanged(event: CustomEvent) {
this.reportID = event.detail;
}
goes to
componentDidLoad() {
document.addEventListener(Reporting.EVENT_REPORT_CHANGED, async (event: CustomEvent)=>{
this.reportID = event.detail;
});
}
Not only it makes it harder to change event names globally, it also doesn't let you put variables inside the Component decorator which makes it harder to handle when you have some components' relations.
I believe this is a typescript limitation not a Stencil limitation right?
馃憤 this would be very useful
Can this be reopened? This is an extremely limiting issue. Using strings everywhere is a recipe for disaster.
Tried giving a string literal with variable/const interpolation:
@Listen("${myvariable}")
Compiles without complaining... unfortunately doesn't appear to work (at least for @Listen())
Most helpful comment
@jthoms1 a decorator is just syntactic sugar for a function that runs at a given lifecycle in a class (which is also just syntactic sugar for a constructor fundtion). A function that accepts a variable as an argument is as basic as it gets in JavaScript. This is definitely a bug, and one that should be fixed. Static analysis be damned if we can't pass a variable to a function.