From ee690f6de6da20ef241bff3364dad88fe525942a Mon Sep 17 00:00:00 2001 From: Steven Orvell Date: Mon, 11 Mar 2019 18:12:43 -0700 Subject: [PATCH 1/3] Schedules `requestUpdate` in `initialize` rather than `connectedCallback` Fixes #594. Ensures an early access of `updateComplete` will not complete before the element has first updated (at connection time). --- src/lib/updating-element.ts | 6 +++--- src/test/lib/updating-element_test.ts | 28 ++++++++++++++++++++++----- 2 files changed, 26 insertions(+), 8 deletions(-) diff --git a/src/lib/updating-element.ts b/src/lib/updating-element.ts index abb2fd93..dde4f4c7 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 8daa277f..062ce89b 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++; } @@ -2219,4 +2214,27 @@ suite('UpdatingElement', () => { await a.updateComplete; 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); + document.body.appendChild(a); + await a.updateComplete; + assert.isTrue(updated); + document.body.removeChild(a); + }); }); From 6c26450c75eeb301e5efc14ce6b09cd9dbbc8e7e Mon Sep 17 00:00:00 2001 From: Steven Orvell Date: Mon, 11 Mar 2019 18:15:27 -0700 Subject: [PATCH 2/3] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index abcd3508..7cab50d2 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)). * Properties annotated with the `@query` and `@queryAll` decorators will now survive property renaming optimizations when used with tsickle and Closure JS Compiler. From 4f4f078ea85904645525276df85f59181a13739d Mon Sep 17 00:00:00 2001 From: Steven Orvell Date: Tue, 12 Mar 2019 14:19:28 -0700 Subject: [PATCH 3/3] Update test to use helper to append/remove elements --- src/test/lib/updating-element_test.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/test/lib/updating-element_test.ts b/src/test/lib/updating-element_test.ts index 062ce89b..0952c541 100644 --- a/src/test/lib/updating-element_test.ts +++ b/src/test/lib/updating-element_test.ts @@ -2232,9 +2232,8 @@ suite('UpdatingElement', () => { }); await new Promise((r) => setTimeout(r, 20)); assert.isFalse(updated); - document.body.appendChild(a); + container.appendChild(a); await a.updateComplete; assert.isTrue(updated); - document.body.removeChild(a); }); });