I implemented a WebComponent in TypeScript that looks like this and is bundled via a WebPack:
class MyTestComponent extends HTMLElement {
// ...
connectedCallback() {
this.config = JSON.parse(this.innerText);
// ...
customElements.define("my-test", MyTestComponent);
In the web page it is used like this:
<my-test>
{
"parts": [
[3, "red"]
]
}
</my-test>
This worked fine using my WebPack genrated test page, but failed if I included the component into another page. I spend some time until I figured out that the defer
attribute at the including script tag makes the difference. If I use defer
the component works fine. If not this.innerText
is empty when connectCallback
is called.
I would like to understand why defer
makes a difference and what's going on in detail. Can somebody explain?
It has nothing to do with TypeScript or WebPack. This is standard Web Components behavior.
The connectedCallback
fires on the opening tag, its inner content is not yet parsed.
With defer
you declare the Custom Element AFTER everything in the DOM is parsed
So to make it work when your Custom Element is defined BEFORE being used,
you have to delay execution till the Components DOM (innnerText or innerHTML
) is parsed.
Easiest is to delay till the Event Loop is empty:
connectedCallback() {
setTimeout(()=>{
this.config = JSON.parse(this.innerText);
});
}
Long answer (when Firefox fired connectedCallback
late, prior to March 2021)
BaseClass Tools, like FAST, Lit, LWC and Hybrids, shield you from this standard behavior...
...making you learn a Tool, not the Technology.