Reputation: 596
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!
Upvotes: 1
Views: 1347
Reputation: 596
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>
Upvotes: 0
Reputation: 31219
It's because when you write:
customElements.define('app-list',
class AppList extends HTMLElement {}
);
the class AppList
is defined only in in the scope of the define()
call. That's why it's not seen when you use it after in the second import file.
Instead, you should first define the class (globally) and then use it in the custom element definition:
// app-list.html
<script>
class AppList extends HTMLElement {
constructor() {
super();
}
}
window.customElements.define('app-list', AppList);
</script>
Upvotes: 4