Search code examples
polymerlit-elementlit-html

Run a function once all children element are _actually_ updated


In lit-html we have the firstUpdated() method to run one-time initialisations once an element is rendered.

What if you need to run a function only once all children within that template are updated? And what if your template includes native form elements and custom ones?

Right now I am doing a terrible:

  firstUpdated () {
    super.firstUpdated()

    setTimeout(() => this.onceChildrenAreUpdated(), 100)
  }

Surely there is a better way? I realise it's tricky, because for lit-element "rendered" means that the DOM is done; it doesn't mean that all elements inside have done whichever initialisation then want to do.

But still...


Solution

  • You can wait for all the children to be updated:

      async firstUpdated () {
        const children = this.shadowRoot.querySelectorAll('*');
        await Promise.all(Array.from(children).map((c) => c.updateComplete));
        this.onceChildrenAreUpdated();
      }
    

    Replace querySelectorAll('*') with something more specific if possible.