Hi, I am working with lit-html and I have found a problem when I try to render a custom element in which I want to set some of its properties in the first render call.
Here is my-element.js:
import { html, render } from 'https://unpkg.com/lit-html/lib/lit-extended.js?module';
class MyElement extends HTMLElement {
constructor() {
super();
this.attachShadow({mode: 'open'});
this._myProp = 1;
}
connectedCallback() {
this.render();
}
get myProp() {
return this._myProp;
}
set myProp(newValue) {
console.log('SET myProp');
this._myProp = newValue;
this.render();
}
render() {
const tmpl = () => html`
<style> :host { display: block; } </style>
${this.myProp}
`;
render(tmpl(), this.shadowRoot);
}
}
window.customElements.define('my-element', MyElement);
And here is the code of app.js:
import { html, render } from 'https://unpkg.com/lit-html/lib/lit-extended.js?module';
import './my-element.js';
const content = (data) => html`<my-element myProp=${data}></my-element>`;
// render(content(), document.body); // 1
// render(content(2), document.body); // 2
setTimeout(() => {
render(content(3), document.body);
}, 1000);
With the first option uncommented in app.js all works as expected: the element does an initial render showing the number 1 and a second later it renders the number 3. The problem comes when we execute the code with the second option uncommented.
The element should render 2 and a second later it should render 3.
The element renders 2 and a second later it doesn't change anything.
I am testing with the element and it seems that, in some manner, lit-html is overriding the myProp setters and getters.
I have make a project in stackblitz in order to illustrate this problem:
https://stackblitz.com/edit/lit-html-custom-elements
This should have been fixed by #385. I'll get a release out soon.
The cause of this issue is the same as the cause in #379, which was solved in #385.
Long story short: the custom element was upgraded too late before #385, which made initial renders set the myProp property _before_ the custom element kicks in. In the constructor of MyElement the property is already set, and it shadows the setter/getter pair on the MyElement prototype.
It worked for a first render with a value of undefined because of another issue in lit-html which makes it skip undefined properties in the first render. This issue has also been solved already, in #377.
In other words: it should work fine if you use version 0.10.0 or in the next release :)
Thanks a lot! @justinfagnani, approximately, when will we get the new release?
I'm having this exact same issue at the moment, but also, using the example above should it be:
html`<my-element myProp=${data}></my-element>`
Or, as it was in Polymer 2
html`<my-element my-prop=${data}></my-element>`
i.e shouldn't slug-case attributes be automatically converted to camelCase property names?
Neither appears works currently - myProp as an attribute becomes myprop and my-prop is ignored.
@justinfagnani can we get an eta on a new release?
EDIT: There are new releases in https://www.npmjs.com/package/lit-html under Versions but it is still dev, and contains the new lit syntax
@KeithHenry What you're seeing is intended behavior. Lit-html should not to kebab-case to camelCase conversion. It should render what you tell it to render. If anything, the web component should do the conversion if necessary.
I'm going to close this issue, as this specific behavior has been fixed. We still have a problem when the render container is disconnected from the document though.