Event for opened fires too soon in <paper-dialog>

Viewed 93

I'm using <paper-dialog> to display an SVG image I'll construct programatically. I need to know the size of the rendered container before I begin. I am waiting for the opened property to change to true however that is apparently too soon as .clientWidth is 0 when it fires however later .clientWidth does provide the correct value.

<paper-dialog class="dialog" opened={{modalOpen}} modal>
     <svg width="100%", height="100%" />
</paper-dialog>

How can I wait for the SVG clientWidth and clientHeight to be computed?

2 Answers

Sometimes JS events are fired before the DOM has time to finish processing, which appears to be the case here.

To get around this (or at least to provide additional clues on what's happening), try putting your code (for the clientWidth property) within a setTimeout() function and give it a zero (0) millisecond timeout. This will simply move your code to the end of the JS execution stack, which should process only after the DOM has finished updating... and subsequently be when the DOM element's size and positioning properties are available.

Here's an example...

modalOpen() {
  setTimeout( () => {  
    /* Your code here... for example... */
    const paperDialog = document.getElementsByTagName("paper-dialog")[0];
    console.log("paperDialog width = ", paperDialog.clientWidth);  
  }, 0);  /* 0 milliseconds = Execute immediately after everything else processes. */
}

WARNING: Using setTimeout() is typically frowned upon since it doesn't fully adhere to asynchronous development and can produce unexpected results (such as firing too soon or not firing as soon as possible). While this approach is quick and can work fine some of the times, triggering and handling events are generally the best way to solve these timing issues.

Polymer's <paper-dialog> implements iron-resizable-behavior so we can listen for the iron-resize event:

disconnectedCallback() {
    super.disconnectedCallback();
    this.removeEventListener('iron-resize', this.onIronResize);
}
Related