New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
updateComplete doesn't guarantee that descendant defined LitElements have been rendered #3538
Comments
|
Utilizing |
override getUpdateComplete() {
const sup = await super.getUpdateComplete();
const kids = await Promise.all(
Array.from(this.children, node => node.updateComplete)
.filter(x => !!x));
return sup && kids.every(x => !!x);
} |
|
Very interesting... so I was working on the following in order to get all descendants and stop at LitElements: function getDescendants(parent, customElementClass) {
const descendants = [];
// Use a depth-first search (DFS) algorithm to traverse the DOM tree
const traverse = node => {
if (node instanceof customElementClass) {
descendants.push(node);
return; // Stop the traversal when a custom element node is encountered
}
for (let i = 0; i < node.childNodes.length; i++) {
traverse(node.childNodes[i]);
}
}
traverse(parent);
return descendants;
}Could I do: override getUpdateComplete() {
const sup = await super.getUpdateComplete();
const kids = await Promise.all(
Array.from(getDescendants(this, LitElement), node => node.updateComplete)
.filter(x => !!x));
return sup && kids.every(x => !!x);
}I don't understand the boolean casting on updateComplete. Why don't you just stop at EDIT: Okay, actually the |
|
our goal is to return a promise that resolves to
so let's
!!(await Promise.resolve(undefined))
// false |
When would an |
|
updateComplete is it would not be truthy when another update was triggered during the previous update cycle. See the docs for more info |
|
Ah, I see now. Thanks. |
|
Updated DFS descendant walker to use duck typing: function getDuckTypedDescendants(parent, qualifyingPropertyName) {
const descendants = [];
// Use a depth-first search (DFS) algorithm to traverse the DOM tree
const traverse = node => {
if( node.hasOwnProperty(qualifyingPropertyName) ) {
descendants.push(node);
return; // Stop the traversal when a custom element node is encountered
}
for( let i = 0; i < node.childNodes.length; i++ ) {
traverse(node.childNodes[i]);
}
};
traverse(parent);
return descendants;
}
// ...
override getUpdateComplete() {
const sup = await super.getUpdateComplete();
const kids = await Promise.all(
Array.from(getDuckTypedDescendants(this, 'updateComplete'), node => node.updateComplete)
.filter(x => !!x));
return sup && kids.every(x => !!x);
} |
|
In the discord, according to @graynorton:
My response:
|
|
Just wanted to contribute one last bit of code, optional implementation: class ExtendedLitElement extends LitElement {
async ready( requireEntireDomTreeReady = false ) {
const thisUpdateComplete = await this.updateComplete;
if( !requireEntireDomTreeReady ) return thisUpdateComplete;
const descendants = await Promise.all(
Array.from(
internal.getDuckTypedDescendants(this, 'updateComplete'),
node => typeof node.ready === 'function' ? node.ready(true) : node.updateComplete
).filter(x => !!x)
);
return thisUpdateComplete && descendants.every(x => !!x);
}
}All your elements would need to extend this ExtendedLitElement class for use, if you're already using a base extended class like this, you could just add the method to it. |
|
Based on this, we added a bit more nuance over when to use |
Should this be an RFC?
Which package is this a feature request for?
Lit Core (lit / lit-html / lit-element / reactive-element)
Description
How hard would it be to add a lifecycle method or promise that lets us know:
thisLitElement have been rendered andupdateCompletestate?Alternatives and Workarounds
Running into this issue has made me more aware that LitElements are basically async which is why statefulness is more-or-less required. However, standard HTML is rendered and ready (from a code standpoint) after it has been appended to the DOM, and offering this promise would allow interoperability with that modality of working with elements and DOM trees.
The text was updated successfully, but these errors were encountered: