lit / lit-element

LEGACY REPO. This repository is for maintenance of the legacy LitElement library. The LitElement base class is now part of the Lit library, which is developed in the lit monorepo.
https://lit-element.polymer-project.org
BSD 3-Clause "New" or "Revised" License
4.49k stars 318 forks source link

Foreach children in template - this.children unexpected behaviour #1152

Closed LukeTOBrien closed 3 years ago

LukeTOBrien commented 3 years ago

Hello there,

I have recently asked this question on SO.
But afther doing a bit more investigation I found some strange behaviour with th this,children property in Chrome and FF.
I have created a simple repo that demonstrates the behaviour.
With FF the behaviour happens because one of the children contains a custom element, if I remove the custom element then it behaves as expected,

1) Inside firstUpdated the property this.children is returning 0 in Chrome when I expect it to be 4.
chrome-console

2) Even more bizarrely, FireFox output 3 children, but when I expand the console log I can see lenght: 4.
(<span> contains a custom element)
ffconsole You can see on the console log that children.length: 3 but when I expand then length: 4 ffconsole-expanded

Does anyone have any idea what is happening have?

LukeTOBrien commented 3 years ago

I have just found this SO question.
If I add a setTimeout in my ComponentOne then all is fine:

    firstUpdated() {
        setTimeout(() => {
        console.log("In FF, this.children == 3, in Chrome it == 0 - Why?")
        console.log("Children length " + this.children.length);
        console.log(this.children);
        console.log("Now in FF when we expand we have 4 children - Why?")
        }. 100);
    }

But the problem is that the children are just ordinary HTML elements, I cannot await updateCompleted


Edit

At the moment this is the hacky solution to my problem.
It seems to me that the render function is being called before the element have fully established, hence it has no children.
Behind the scenes do you await the whenDefined?

justinfagnani commented 3 years ago

The best way to handle children is to assume that they change at any time (they can) and dynamically handle children changing via a slot and the slotchage event.

LukeTOBrien commented 3 years ago

hmmm, I wonder would it be possible to use asyncReplace to render the children within the template?

Now I understand more about the event loop and slots I will do some more investegation.

LukeTOBrien commented 3 years ago

I guess I will close this as it is expected browser behaviour...