Skip to content

Commit 7151eae

Browse files
Balint Meromhevery
Balint Mero
authored andcommittedJul 18, 2019
fix(elements): handle falsy initial value (#31604)
Fixes #30834 PR Close #31604
1 parent 376ad9c commit 7151eae

File tree

2 files changed

+46
-9
lines changed

2 files changed

+46
-9
lines changed
 

‎packages/elements/src/component-factory-strategy.ts

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -125,12 +125,12 @@ export class ComponentNgElementStrategy implements NgElementStrategy {
125125
* cached and set when the component is created.
126126
*/
127127
setInputValue(property: string, value: any): void {
128-
if (strictEquals(value, this.getInputValue(property))) {
128+
if (!this.componentRef) {
129+
this.initialInputValues.set(property, value);
129130
return;
130131
}
131132

132-
if (!this.componentRef) {
133-
this.initialInputValues.set(property, value);
133+
if (strictEquals(value, this.getInputValue(property))) {
134134
return;
135135
}
136136

@@ -164,9 +164,8 @@ export class ComponentNgElementStrategy implements NgElementStrategy {
164164
/** Set any stored initial inputs on the component's properties. */
165165
protected initializeInputs(): void {
166166
this.componentFactory.inputs.forEach(({propName}) => {
167-
const initialValue = this.initialInputValues.get(propName);
168-
if (initialValue) {
169-
this.setInputValue(propName, initialValue);
167+
if (this.initialInputValues.has(propName)) {
168+
this.setInputValue(propName, this.initialInputValues.get(propName));
170169
} else {
171170
// Keep track of inputs that were not initialized in case we need to know this for
172171
// calling ngOnChanges with SimpleChanges

‎packages/elements/test/component-factory-strategy_spec.ts

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,11 @@ describe('ComponentFactoryNgElementStrategy', () => {
4545
beforeEach(() => {
4646
// Set up an initial value to make sure it is passed to the component
4747
strategy.setInputValue('fooFoo', 'fooFoo-1');
48+
strategy.setInputValue('falsyUndefined', undefined);
49+
strategy.setInputValue('falsyNull', null);
50+
strategy.setInputValue('falsyEmpty', '');
51+
strategy.setInputValue('falsyFalse', false);
52+
strategy.setInputValue('falsyZero', 0);
4853
strategy.connect(document.createElement('div'));
4954
});
5055

@@ -73,11 +78,39 @@ describe('ComponentFactoryNgElementStrategy', () => {
7378
expect(componentRef.instance.fooFoo).toBe('fooFoo-1');
7479
});
7580

81+
it('should initialize the component with falsy initial values', () => {
82+
expect(strategy.getInputValue('falsyUndefined')).toEqual(undefined);
83+
expect(componentRef.instance.falsyUndefined).toEqual(undefined);
84+
expect(strategy.getInputValue('falsyNull')).toEqual(null);
85+
expect(componentRef.instance.falsyNull).toEqual(null);
86+
expect(strategy.getInputValue('falsyEmpty')).toEqual('');
87+
expect(componentRef.instance.falsyEmpty).toEqual('');
88+
expect(strategy.getInputValue('falsyFalse')).toEqual(false);
89+
expect(componentRef.instance.falsyFalse).toEqual(false);
90+
expect(strategy.getInputValue('falsyZero')).toEqual(0);
91+
expect(componentRef.instance.falsyZero).toEqual(0);
92+
});
93+
7694
it('should call ngOnChanges with the change', () => {
77-
expectSimpleChanges(
78-
componentRef.instance.simpleChanges[0],
79-
{fooFoo: new SimpleChange(undefined, 'fooFoo-1', false)});
95+
expectSimpleChanges(componentRef.instance.simpleChanges[0], {
96+
fooFoo: new SimpleChange(undefined, 'fooFoo-1', false),
97+
falsyNull: new SimpleChange(undefined, null, false),
98+
falsyEmpty: new SimpleChange(undefined, '', false),
99+
falsyFalse: new SimpleChange(undefined, false, false),
100+
falsyZero: new SimpleChange(undefined, 0, false),
101+
});
80102
});
103+
104+
it('should call ngOnChanges with proper firstChange value', fakeAsync(() => {
105+
strategy.setInputValue('falsyUndefined', 'notanymore');
106+
strategy.setInputValue('barBar', 'barBar-1');
107+
tick(16); // scheduler waits 16ms if RAF is unavailable
108+
(strategy as any).detectChanges();
109+
expectSimpleChanges(componentRef.instance.simpleChanges[1], {
110+
falsyUndefined: new SimpleChange(undefined, 'notanymore', false),
111+
barBar: new SimpleChange(undefined, 'barBar-1', true),
112+
});
113+
}));
81114
});
82115

83116
it('should not call ngOnChanges if not present on the component', () => {
@@ -234,6 +267,11 @@ export class FakeComponentFactory extends ComponentFactory<any> {
234267
return [
235268
{propName: 'fooFoo', templateName: 'fooFoo'},
236269
{propName: 'barBar', templateName: 'my-bar-bar'},
270+
{propName: 'falsyUndefined', templateName: 'falsyUndefined'},
271+
{propName: 'falsyNull', templateName: 'falsyNull'},
272+
{propName: 'falsyEmpty', templateName: 'falsyEmpty'},
273+
{propName: 'falsyFalse', templateName: 'falsyFalse'},
274+
{propName: 'falsyZero', templateName: 'falsyZero'},
237275
];
238276
}
239277

0 commit comments

Comments
 (0)