Asked By: Anonymous
Problem Description
It seems there is a timing issue with Polymer (2.x) when querying for nodes embedded in a template element right after connectedCallback()
has been called. I would expect that the first call of this.shadowRoot.querySelectorAll('h1')
in the sample below should return all <h1>
nodes within the template.
The Mozilla Custom Element Doc states:
connectedCallback()
Called when the element is inserted into a document, including into a shadow tree
To my understanding, all templates should be already stamped out at this time.
As can be seen in the snippet, the first query returns an empty list. However, the nodes are returned if the query is delayed.
Is there anything I’m missing here?
Sample Code
<!DOCTYPE html>_x000D_
<html>_x000D_
_x000D_
<head>_x000D_
<meta charset="utf-8">_x000D_
_x000D_
<base href="https://polygit.org/components/">_x000D_
<a href="http://webcomponentsjs/webcomponents-lite.js">http://webcomponentsjs/webcomponents-lite.js</a>_x000D_
_x000D_
<link rel="import" href="polymer/polymer-element.html">_x000D_
<link rel="import" href="polymer/lib/elements/dom-repeat.html">_x000D_
</head>_x000D_
_x000D_
<body>_x000D_
<dom-module id="x-elem">_x000D_
<template>_x000D_
<template is="dom-repeat" items="[[testItems]]">_x000D_
<h1>[[item]]</h1>_x000D_
</template>_x000D_
</template>_x000D_
<script>_x000D_
class XElem extends Polymer.Element {_x000D_
static get is() { return 'x-elem' }_x000D_
static get properties() {_x000D_
return {_x000D_
'testItems': {_x000D_
type: Array,_x000D_
value: function () {_x000D_
return [1, 2, 3];_x000D_
}_x000D_
}_x000D_
}_x000D_
}_x000D_
_x000D_
ready(){_x000D_
super.ready();_x000D_
}_x000D_
_x000D_
connectedCallback() {_x000D_
super.connectedCallback();_x000D_
console.log("Number of nodes after connectedCallback: ", this.shadowRoot.querySelectorAll('h1').length);_x000D_
var callback = () => { _x000D_
console.log("Number of nodes after timeout: ", this.shadowRoot.querySelectorAll('h1').length); _x000D_
}_x000D_
setTimeout(callback, 100);_x000D_
}_x000D_
}_x000D_
_x000D_
customElements.define(XElem.is, XElem);_x000D_
</script>_x000D_
</dom-module>_x000D_
_x000D_
<x-elem></x-elem>_x000D_
</body>_x000D_
_x000D_
</html>
_x000D_
_x000D_
x000D
Solution
Answered By: Anonymous
The connectedCallback
does not imply the element has been rendered. You could use Polymer.RenderStatus.afterNextRender
for that:
connectedCallback() {
super.connectedCallback();
Polymer.RenderStatus.afterNextRender(this, () => {
console.log('Number of nodes after connectedCallback: ', this.shadowRoot.querySelectorAll('h1').length);
});
}