I have a custom Web Component, <app-list>
that I'm trying to extend into <calcs-list>
.
// app-list.html
<script>
window.customElements.define('app-list',
class AppList extends HTMLElement {
constructor() {
super();
}
}
);
</script>
In calcs-list.html I've got:
<link rel="import" href="app-list.html">
<script>
window.customElements.define('calcs-list',
class CalcsList extends AppList {
constructor() {
super();
console.log('CalcsList constructed');
}
}
);
</script>
However, I get the error
Uncaught ReferenceError: AppList is not defined at calcs-list.html:11
Line 11 references class CalcsList extends AppList {
Both files are siblings of the same folder. I tried using an absolute path when importing app-list.html
into calcs-list.html
but got the same result.
I also tried importing both components into my main index.html file:
//index.html
<link rel="import" href="/src/components/app-list.html">
<link rel="import" href="/src/components/calcs-list.html">
<app-list></app-list>
<calcs-list></calcs-list>
But experience the same result.
The app-list
component works in my application without any issue.
I'm scratching my head on this one and because Web Components are considerably new, there isn't a whole lot of troubleshooting info online, especially with V1 of Web Components.
Thanks!
Thanks to @Supersharp, I re-wrote my custom component declaration as such:
// app-list.html
<script>
class AppList extends HTMLElement { ... }
customElements.define('app-list', AppList);
</script>
And calcs-list.html
:
<script>
class CalcsList extends AppList { ... }
customElements.define('calcs-list', CalcsList);
</script>
A note of caution: If you declare a tag within the parent element (the element that's being extended) with an id
then this will conflict with the extended element's call to super()
.
For example:
<template id="app-list">
...
</template>
The way to work around this is to use a JavaScript string literal, as referenced by the Google Developers, and not use an id
at all.
<script>
let template = document.createElement('template');
template.innerHTML = `
<style> ... </style>
<div> ... </div>
`;
class AppList extends HTMLElement {
constructor() {
super();
let shadowRoot = this.attachShadow({mode: 'open'}).appendChild(template.content.cloneNode(true));
}
}
</script>