Custom-element could be initialised asynchronously, for instance after lazy loading its definition class.
Lets take a look at this example, we have an element sitting in the DOM that is not initialised yet:
<component-with-async-init></component-with-async-init>
Before initialisation we set a value
property of this element:
querySelector('component-with-async-init').value = "GETTERS SETTERS ARE KILLED"
Then we init this element by defining it as a custom element. As you can see its definition class has getter and setter for value
property.
class ComponentWithAsyncInit extends HTMLElement{
static get is() {
return 'component-with-async-init'
}
get value(){
console.log("Getting value")
return "VALUE FROM GETTER"
}
set value(v){
console.log("Setting value")
}
}
window.customElements.define(ComponentWithAsyncInit.is, ComponentWithAsyncInit);
Getters and setters(or any method) are now killed, as you can see:
querySelector('component-with-async-init').value //"GETTERS SETTERS ARE KILLED"
I observe this behaviour in latest Safari, Firefox and Chrome, others not tested. This problem affects Polymer and Lit-Element libraries as well as pure custom elements. Seems like it works the same way in every browser.
Question: Is it really an expected behaviour? Getters and Setters and any methods get wiped out if a property was set before element definition. If yes, what will be a workaround since we usually can't control when element value is set
Snippet:
document.querySelector('component-with-async-init').value = "SETTERS GETTERS KILLED"
document.querySelector('component-with-async-init').getSomeValue = "GET SOME VALUE KILLED"
class ComponentWithAsyncInit extends HTMLElement{
static get is() {
return 'component-with-async-init'
}
get value(){
console.log("Getting value")
return "VALUE FROM GETTER"
}
set value(v){
console.log("Setting value")
}
getSomeValue(){
return "SOME VALUE"
}
}
window.customElements.define(ComponentWithAsyncInit.is, ComponentWithAsyncInit);
console.log("getSomeValue method:")
console.log(document.querySelector('component-with-async-init').getSomeValue)
console.log("Reading value:")
console.log(document.querySelector('component-with-async-init').value)
<component-with-async-init></component-with-async-init>