diff --git a/src/lib/updating-element.ts b/src/lib/updating-element.ts index 6ae2c74d..226e4ec1 100644 --- a/src/lib/updating-element.ts +++ b/src/lib/updating-element.ts @@ -506,6 +506,7 @@ export abstract class UpdatingElement extends HTMLElement { const needsFirstUpdate = !(this._updateState & STATE_HAS_UPDATED); this._markUpdated(); if (needsFirstUpdate) { + this._updateState = this._updateState | STATE_HAS_UPDATED; this.firstUpdated(changedProperties); } this.updated(changedProperties); @@ -513,10 +514,9 @@ export abstract class UpdatingElement extends HTMLElement { this._markUpdated(); } } - private _markUpdated() { this._changedProperties = new Map(); - this._updateState = this._updateState & ~STATE_UPDATE_REQUESTED | STATE_HAS_UPDATED; + this._updateState = this._updateState & ~STATE_UPDATE_REQUESTED; } /** diff --git a/src/test/lit-element_test.ts b/src/test/lit-element_test.ts index d21a7274..1247bb2f 100644 --- a/src/test/lit-element_test.ts +++ b/src/test/lit-element_test.ts @@ -1063,6 +1063,56 @@ suite('LitElement', () => { assert.equal(el.wasFirstUpdated, 1); }); + test( + '`firstUpdated` called when element first updates even if first `shouldUpdate` returned false', async () => { + class E extends LitElement { + + @property() + foo = 1; + + triedToUpdatedCount = 0; + wasUpdatedCount = 0; + wasFirstUpdated = 0; + changedProperties: PropertyValues|undefined; + + shouldUpdate() { + this.triedToUpdatedCount++; + return this.triedToUpdatedCount > 1; + } + + update(changedProperties: PropertyValues) { + this.wasUpdatedCount++; + super.update(changedProperties); + } + + render() { return html ``; } + + firstUpdated(changedProperties: PropertyValues) { + this.changedProperties = changedProperties; + this.wasFirstUpdated++; + } + } + + customElements.define(generateElementName(), E); + const el = new E(); + container.appendChild(el); + await el.updateComplete; + const testMap = new Map(); + testMap.set('foo', undefined); + assert.equal(el.triedToUpdatedCount, 1); + assert.equal(el.wasUpdatedCount, 0); + assert.equal(el.wasFirstUpdated, 0); + await el.requestUpdate(); + assert.deepEqual(el.changedProperties, testMap); + assert.equal(el.triedToUpdatedCount, 2); + assert.equal(el.wasUpdatedCount, 1); + assert.equal(el.wasFirstUpdated, 1); + await el.requestUpdate(); + assert.equal(el.triedToUpdatedCount, 3); + assert.equal(el.wasUpdatedCount, 2); + assert.equal(el.wasFirstUpdated, 1); + }); + test( 'render lifecycle order', async () => { class E extends LitElement {