Skip to content

Commit fcd92a8

Browse files
committed
FIO-10337: Fixed the normalize processor to handle null and undefined values in a much better way. (#275)
* FIO-10337: Refactored the core data processors to significantly improve performance. * Update postProcess function signature. * Make sure to not autoset an array value if the component is required. * Make sure to add set paths to the filter. * Make sure that deliberate filtered paths are not included. * FIO-10337: Refactored the normalize processor to handle null and undefined components better.
1 parent 694ea4e commit fcd92a8

File tree

6 files changed

+107
-30
lines changed

6 files changed

+107
-30
lines changed

src/process/__tests__/process.test.ts

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6421,5 +6421,86 @@ describe('Process Tests', function () {
64216421
submission.data = context.data;
64226422
expect(context.scope.errors.length).to.equal(0);
64236423
});
6424+
6425+
it('Should not add undefined values for components.', async function () {
6426+
const form = {
6427+
components: [
6428+
{
6429+
input: true,
6430+
tableView: true,
6431+
inputType: 'text',
6432+
inputMask: '',
6433+
label: 'fname',
6434+
key: 'fname',
6435+
placeholder: '',
6436+
prefix: '',
6437+
suffix: '',
6438+
multiple: false,
6439+
defaultValue: '',
6440+
protected: false,
6441+
unique: false,
6442+
persistent: true,
6443+
validate: {
6444+
required: true,
6445+
minLength: '',
6446+
maxLength: '',
6447+
pattern: '',
6448+
custom: '',
6449+
customPrivate: false,
6450+
},
6451+
conditional: {
6452+
show: '',
6453+
when: null,
6454+
eq: '',
6455+
},
6456+
type: 'textfield',
6457+
},
6458+
{
6459+
input: true,
6460+
tableView: true,
6461+
inputType: 'text',
6462+
inputMask: '',
6463+
label: 'lname',
6464+
key: 'lname',
6465+
placeholder: '',
6466+
prefix: '',
6467+
suffix: '',
6468+
multiple: false,
6469+
defaultValue: '',
6470+
protected: false,
6471+
unique: false,
6472+
persistent: true,
6473+
validate: {
6474+
required: true,
6475+
minLength: '',
6476+
maxLength: '',
6477+
pattern: '',
6478+
custom: '',
6479+
customPrivate: false,
6480+
},
6481+
conditional: {
6482+
show: '',
6483+
when: null,
6484+
eq: '',
6485+
},
6486+
type: 'textfield',
6487+
},
6488+
],
6489+
};
6490+
const submission = {
6491+
data: {},
6492+
};
6493+
const context = {
6494+
form,
6495+
submission,
6496+
data: submission.data,
6497+
components: form.components,
6498+
processors: Processors,
6499+
scope: {},
6500+
};
6501+
processSync(context);
6502+
assert(!context.data.hasOwnProperty('fname'));
6503+
assert(!context.data.hasOwnProperty('lname'));
6504+
});
64246505
});
64256506
});

src/process/calculation/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ export const calculateProcessSync: ProcessorFnSync<CalculationScope> = (
5151
});
5252
set(data, path, newValue);
5353
if (!scope.filter) scope.filter = {};
54-
if (!scope.filter.hasOwnProperty(path)) {
54+
if (!(scope as any).clearHidden?.hasOwnProperty(path)) {
5555
scope.filter[path] = true;
5656
}
5757
}

src/process/defaultValue/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ function setDefaultValue(context: DefaultValueContext, defaultValue: any) {
4949

5050
// If this component is not already included in the filter and is not a number, then include it from the default.
5151
if (!scope.filter) scope.filter = {};
52-
if (!scope.filter.hasOwnProperty(path) && getModelType(component) !== 'number') {
52+
if (!(scope as any).clearHidden?.hasOwnProperty(path) && getModelType(component) !== 'number') {
5353
scope.filter[path] = true;
5454
}
5555
}

src/process/fetch/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ export const fetchProcess: ProcessorFn<FetchScope> = async (context: FetchContex
102102

103103
// Make sure the value does not get filtered for now...
104104
if (!scope.filter) scope.filter = {};
105-
if (!scope.filter.hasOwnProperty(path)) {
105+
if (!(scope as any).clearHidden?.hasOwnProperty(path)) {
106106
scope.filter[path] = true;
107107
}
108108
scope.fetched[path] = get(row, key);

src/process/normalize/index.ts

Lines changed: 22 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import {
1919
NumberComponent,
2020
} from 'types';
2121

22-
type NormalizeScope = DefaultValueScope & {
22+
export type NormalizeScope = DefaultValueScope & {
2323
normalize?: {
2424
[path: string]: any;
2525
};
@@ -371,45 +371,41 @@ export const normalizeProcessSync: ProcessorFnSync<NormalizeScope> = (context) =
371371
type: component.type,
372372
normalized: false,
373373
};
374-
// First check for component-type-specific transformations
374+
let newValue = value;
375375
if (isAddressComponent(component)) {
376-
set(data, path, normalizeAddressComponentValue(component, value));
377-
scope.normalize[path].normalized = true;
376+
newValue = normalizeAddressComponentValue(component, value);
378377
} else if (isDayComponent(component)) {
379-
set(data, path, normalizeDayComponentValue(component, form, value));
380-
scope.normalize[path].normalized = true;
378+
newValue = normalizeDayComponentValue(component, form, value);
381379
} else if (isEmailComponent(component)) {
382-
if (value && typeof value === 'string') {
383-
set(data, path, value.toLowerCase());
384-
scope.normalize[path].normalized = true;
385-
}
380+
newValue = value && isString(value) ? value.trim().toLowerCase() : value;
386381
} else if (isRadioComponent(component)) {
387-
set(data, path, normalizeRadioComponentValue(value, component.dataType));
388-
scope.normalize[path].normalized = true;
382+
newValue = normalizeRadioComponentValue(value, component.dataType);
389383
} else if (isSelectComponent(component)) {
390-
set(data, path, normalizeSelectComponentValue(component, value));
391-
scope.normalize[path].normalized = true;
384+
newValue = normalizeSelectComponentValue(component, value);
392385
} else if (isSelectBoxesComponent(component)) {
393-
set(data, path, normalizeSelectBoxesComponentValue(value));
394-
scope.normalize[path].normalized = true;
386+
newValue = normalizeSelectBoxesComponentValue(value);
395387
} else if (isTagsComponent(component)) {
396-
set(data, path, normalizeTagsComponentValue(component, value));
397-
scope.normalize[path].normalized = true;
388+
newValue = normalizeTagsComponentValue(component, value);
398389
} else if (isTextFieldComponent(component)) {
399-
set(data, path, normalizeTextFieldComponentValue(component, defaultValues, value, path));
400-
scope.normalize[path].normalized = true;
390+
newValue = normalizeTextFieldComponentValue(component, defaultValues, value, path);
401391
} else if (isTimeComponent(component)) {
402-
set(data, path, normalizeTimeComponentValue(component, value));
403-
scope.normalize[path].normalized = true;
392+
newValue = normalizeTimeComponentValue(component, value);
404393
} else if (isNumberComponent(component)) {
405-
set(data, path, normalizeNumberComponentValue(component, value));
406-
scope.normalize[path].normalized = true;
394+
newValue = normalizeNumberComponentValue(component, value);
407395
}
408396

409-
// Next perform component-type-agnostic transformations (i.e. super())
410397
if (component.multiple && !component.validate?.required && !Array.isArray(value)) {
411-
set(data, path, value ? [value] : []);
398+
newValue = value ? [value] : [];
399+
}
400+
401+
if (newValue === undefined || newValue === null) {
402+
scope.filter = scope.filter || {};
403+
scope.filter[path] = false;
404+
} else if (value !== newValue && !(scope as any).clearHidden?.hasOwnProperty(path)) {
405+
set(data, path, newValue);
412406
scope.normalize[path].normalized = true;
407+
scope.filter = scope.filter || {};
408+
scope.filter[path] = true;
413409
}
414410
};
415411

src/utils/logic.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ export function setValueProperty(context: LogicContext, action: LogicActionValue
141141
) {
142142
set(data, path, newValue);
143143
if (!scope.filter) scope.filter = {};
144-
if (!scope.filter.hasOwnProperty(path)) {
144+
if (!(scope as any).clearHidden?.hasOwnProperty(path)) {
145145
scope.filter[path] = true;
146146
}
147147
return true;

0 commit comments

Comments
 (0)