Skip to content

Commit aec420a

Browse files
committed
Fixed issue with customValidate errors not being cleared.
1 parent 6939861 commit aec420a

File tree

1 file changed

+41
-13
lines changed

1 file changed

+41
-13
lines changed

packages/core/src/components/Form.tsx

Lines changed: 41 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,8 @@ import {
3535
ValidatorType,
3636
Experimental_DefaultFormStateBehavior,
3737
Experimental_CustomMergeAllOf,
38-
// FormValidation,
38+
createErrorHandler,
39+
unwrapErrorHandler,
3940
} from '@rjsf/utils';
4041
import _forEach from 'lodash/forEach';
4142
import _get from 'lodash/get';
@@ -275,8 +276,6 @@ export default class Form<
275276
*/
276277
formElement: RefObject<any>;
277278

278-
private customValidationErrors: RJSFValidationError[] = [];
279-
280279
/** Constructs the `Form` from the `props`. Will setup the initial state from the props. It will also call the
281280
* `onChange` handler if the initially provided `formData` is modified to add missing default values as part of the
282281
* state construction.
@@ -522,9 +521,21 @@ export default class Form<
522521
return shouldRender(this, nextProps, nextState);
523522
}
524523

525-
// private customValidateCB = (formData: T | undefined, errors: FormValidation<T>, uiSchema?: UiSchema<T, S, F>): FormValidation<T> => {
526-
// const errorHandler = customValidate(newFormData, createErrorHandler<T>(newFormData), uiSchema);
527-
// };
524+
/** Gets the previously raised customValidate errors.
525+
*
526+
* @returns the previous customValidate errors
527+
*/
528+
private getPreviousCustomValidateErrors = (): ErrorSchema<T> => {
529+
const { customValidate, uiSchema } = this.props;
530+
const prevFormData = this.state.formData as T;
531+
let customValidateErrors = {};
532+
if (typeof customValidate === 'function') {
533+
const errorHandler = customValidate(prevFormData, createErrorHandler<T>(prevFormData), uiSchema);
534+
const userErrorSchema = unwrapErrorHandler<T>(errorHandler);
535+
customValidateErrors = userErrorSchema;
536+
}
537+
return customValidateErrors;
538+
};
528539

529540
/** Validates the `formData` against the `schema` using the `altSchemaUtils` (if provided otherwise it uses the
530541
* `schemaUtils` in the state), returning the results.
@@ -651,18 +662,39 @@ export default class Form<
651662
if (resolvedSchema?.type !== 'object' && resolvedSchema?.type !== 'array') {
652663
filteredErrors.__errors = schemaErrors.__errors;
653664
}
665+
666+
const prevCustomValidateErrors = this.getPreviousCustomValidateErrors();
667+
// Filtering out the previous raised customValidate errors so that they are cleared when no longer valid.
668+
const filterPreviousCustomErrors = (errors: string[] = [], prevCustomErrors: string[]) => {
669+
if (errors.length === 0) {
670+
return errors;
671+
}
672+
673+
return errors.filter((error) => {
674+
return !prevCustomErrors.includes(error);
675+
});
676+
};
677+
654678
// Removing undefined, null and empty errors.
655-
const filterNilOrEmptyErrors = (errors: any): ErrorSchema<T> => {
679+
const filterNilOrEmptyErrors = (errors: any, previousCustomValidateErrors: any = {}): ErrorSchema<T> => {
656680
_forEach(errors, (errorAtKey, errorKey: keyof typeof errors) => {
681+
const prevCustomValidateErrorAtKey = previousCustomValidateErrors[errorKey];
657682
if (_isNil(errorAtKey)) {
658683
delete errors[errorKey];
684+
} else if (
685+
isObject(errorAtKey) &&
686+
isObject(prevCustomValidateErrorAtKey) &&
687+
Array.isArray(prevCustomValidateErrorAtKey?.__errors)
688+
) {
689+
// if previous customValidate error is an object and has __errors array, filter out the errors previous customValidate errors.
690+
errors[errorKey] = filterPreviousCustomErrors(errorAtKey.__errors, prevCustomValidateErrorAtKey.__errors);
659691
} else if (typeof errorAtKey === 'object' && !Array.isArray(errorAtKey.__errors)) {
660-
filterNilOrEmptyErrors(errorAtKey);
692+
filterNilOrEmptyErrors(errorAtKey, previousCustomValidateErrors[errorKey]);
661693
}
662694
});
663695
return errors;
664696
};
665-
return filterNilOrEmptyErrors(filteredErrors);
697+
return filterNilOrEmptyErrors(filteredErrors, prevCustomValidateErrors);
666698
}
667699

668700
/** Function to handle changes made to a field in the `Form`. This handler receives an entirely new copy of the
@@ -710,12 +742,8 @@ export default class Form<
710742
errors = merged.errors;
711743
}
712744
// Merging 'newErrorSchema' into 'errorSchema' to display the custom raised errors.
713-
console.log('newErrorSchema****', newErrorSchema);
714745
if (newErrorSchema) {
715746
const filteredErrors = this.filterErrorsBasedOnSchema(newErrorSchema, retrievedSchema, newFormData);
716-
console.log('filteredErrors', filteredErrors);
717-
console.log('newFormData', newFormData);
718-
console.log('filteredErrors formData', formData);
719747
errorSchema = mergeObjects(errorSchema, filteredErrors, 'preventDuplicates') as ErrorSchema<T>;
720748
}
721749
state = {

0 commit comments

Comments
 (0)