diff --git a/CHANGELOG.md b/CHANGELOG.md index a90ae761..530bdafe 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). * `LitElement.renderRoot` is now `public readonly` instead of `protected`. ### Fixed +* Initial update is scheduled at construction time rather than connected time ([#594](https://github.com/Polymer/lit-element/issues/594)). * A reflecting property set immediately after a corresponding attribute now reflects properly ([#592](https://github.com/Polymer/lit-element/issues/592)). * Properties annotated with the `@query` and `@queryAll` decorators will now diff --git a/src/lib/updating-element.ts b/src/lib/updating-element.ts index 4cca413d..ab21ed59 100644 --- a/src/lib/updating-element.ts +++ b/src/lib/updating-element.ts @@ -441,6 +441,8 @@ export abstract class UpdatingElement extends HTMLElement { */ protected initialize() { this._saveInstanceProperties(); + // ensures first update will be caught by an early access of `updateComplete` + this.requestUpdate(); } /** @@ -484,15 +486,13 @@ export abstract class UpdatingElement extends HTMLElement { connectedCallback() { this._updateState = this._updateState | STATE_HAS_CONNECTED; - // Ensure connection triggers an update. Updates cannot complete before + // Ensure first connection completes an update. Updates cannot complete before // connection and if one is pending connection the `_hasConnectionResolver` // will exist. If so, resolve it to complete the update, otherwise // requestUpdate. if (this._hasConnectedResolver) { this._hasConnectedResolver(); this._hasConnectedResolver = undefined; - } else { - this.requestUpdate(); } } diff --git a/src/test/lib/updating-element_test.ts b/src/test/lib/updating-element_test.ts index d10d3b0e..c5f6b45c 100644 --- a/src/test/lib/updating-element_test.ts +++ b/src/test/lib/updating-element_test.ts @@ -2202,11 +2202,6 @@ suite('UpdatingElement', () => { @property() foo = 5; - constructor() { - super(); - this.requestUpdate(); - } - updated(_changedProperties: Map) { this.updatedCalledCount++; } @@ -2220,6 +2215,28 @@ suite('UpdatingElement', () => { assert.equal(a.updatedCalledCount, 1); }); + test('early access of updateComplete waits until first update', async() => { + class A extends UpdatingElement { + didUpdate = false; + + updated(_changedProperties: Map) { + this.didUpdate = true; + } + } + customElements.define(generateElementName(), A); + const a = new A(); + let updated = false; + a.updateComplete.then(() => { + updated = true; + assert.isTrue(a.didUpdate); + }); + await new Promise((r) => setTimeout(r, 20)); + assert.isFalse(updated); + container.appendChild(a); + await a.updateComplete; + assert.isTrue(updated); + }); + test('property reflects after setting attribute in same update cycle', async () => { class A extends UpdatingElement {