diff --git a/packages/elements/src/component-factory-strategy.ts b/packages/elements/src/component-factory-strategy.ts index 6480045dae..fafe335b84 100644 --- a/packages/elements/src/component-factory-strategy.ts +++ b/packages/elements/src/component-factory-strategy.ts @@ -133,7 +133,11 @@ export class ComponentNgElementStrategy implements NgElementStrategy { return; } - if (strictEquals(value, this.getInputValue(property))) { + // Ignore the value if it is strictly equal to the current value, except if it is `undefined` + // and this is the first change to the value (because an explicit `undefined` _is_ strictly + // equal to not having a value set at all, but we still need to record this as a change). + if (strictEquals(value, this.getInputValue(property)) && + !((value === undefined) && this.unchangedInputs.has(property))) { return; } diff --git a/packages/elements/test/component-factory-strategy_spec.ts b/packages/elements/test/component-factory-strategy_spec.ts index 4a99800a6b..7887b55abf 100644 --- a/packages/elements/test/component-factory-strategy_spec.ts +++ b/packages/elements/test/component-factory-strategy_spec.ts @@ -94,6 +94,7 @@ describe('ComponentFactoryNgElementStrategy', () => { it('should call ngOnChanges with the change', () => { expectSimpleChanges(componentRef.instance.simpleChanges[0], { fooFoo: new SimpleChange(undefined, 'fooFoo-1', true), + falsyUndefined: new SimpleChange(undefined, undefined, true), falsyNull: new SimpleChange(undefined, null, true), falsyEmpty: new SimpleChange(undefined, '', true), falsyFalse: new SimpleChange(undefined, false, true), @@ -104,11 +105,13 @@ describe('ComponentFactoryNgElementStrategy', () => { it('should call ngOnChanges with proper firstChange value', fakeAsync(() => { strategy.setInputValue('fooFoo', 'fooFoo-2'); strategy.setInputValue('barBar', 'barBar-1'); + strategy.setInputValue('falsyUndefined', 'notanymore'); tick(16); // scheduler waits 16ms if RAF is unavailable (strategy as any).detectChanges(); expectSimpleChanges(componentRef.instance.simpleChanges[1], { fooFoo: new SimpleChange('fooFoo-1', 'fooFoo-2', false), barBar: new SimpleChange(undefined, 'barBar-1', true), + falsyUndefined: new SimpleChange(undefined, 'notanymore', false), }); })); });