Skip to content

Commit e210175

Browse files
authored
Merge pull request #895 from rvsia/fixErrorsFormat
fix(manager): fix error format inconsistency
2 parents abb2121 + b522406 commit e210175

File tree

2 files changed

+52
-5
lines changed

2 files changed

+52
-5
lines changed

packages/form-state-manager/src/tests/utils/manager-api.test.js

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1105,6 +1105,42 @@ describe('managerApi', () => {
11051105
expect(managerApi().hasValidationErrors).toEqual(true);
11061106
});
11071107

1108+
it('should fail sync level validation and set field error', () => {
1109+
const render = jest.fn();
1110+
const managerApi = createManagerApi({ validate: () => ({ nested: { foo: 'some-very-evil-error' } }) });
1111+
const { registerField } = managerApi();
1112+
1113+
registerField({ name: 'nested.foo', render });
1114+
1115+
expect(managerApi().getState().errors).toEqual({ nested: { foo: 'some-very-evil-error' } });
1116+
expect(managerApi().getState().valid).toEqual(false);
1117+
expect(managerApi().getState().invalid).toEqual(true);
1118+
expect(managerApi().getState().validating).toEqual(false);
1119+
expect(managerApi().hasValidationErrors).toEqual(true);
1120+
expect(managerApi().getFieldState('nested.foo').meta.error).toEqual('some-very-evil-error');
1121+
});
1122+
1123+
it('should fail async level validation and set field error', (done) => {
1124+
const asyncValidateWithError = () => Promise.reject({ nested: { foo: 'some-very-evil-error' } });
1125+
1126+
const render = jest.fn();
1127+
const managerApi = createManagerApi({ validate: asyncValidateWithError });
1128+
const { registerField } = managerApi();
1129+
1130+
registerField({ name: 'nested.foo', render });
1131+
1132+
setImmediate(() => {
1133+
expect(managerApi().getState().valid).toEqual(false);
1134+
expect(managerApi().getState().invalid).toEqual(true);
1135+
expect(managerApi().getState().validating).toEqual(false);
1136+
expect(managerApi().hasValidationErrors).toEqual(true);
1137+
expect(managerApi().getState().errors).toEqual({ nested: { foo: 'some-very-evil-error' } });
1138+
expect(managerApi().getFieldState('nested.foo').meta.error).toEqual('some-very-evil-error');
1139+
1140+
done();
1141+
});
1142+
});
1143+
11081144
it('should pass async level validation', () => {
11091145
jest.useFakeTimers();
11101146
const render = jest.fn();

packages/form-state-manager/src/utils/manager-api.ts

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,7 @@ const createManagerApi: CreateManagerApi = ({
254254
let silentRender: string[] = [];
255255
let runningValidators = 0;
256256
let flatSubmitErrors: AnyObject = {};
257+
let flatErrors: AnyObject = {};
257258

258259
function updateRunningValidators(increment: number): void {
259260
runningValidators = Math.max(runningValidators + increment, 0);
@@ -460,6 +461,7 @@ const createManagerApi: CreateManagerApi = ({
460461
if (isPromise(result)) {
461462
const asyncResult = result as Promise<FormLevelError>;
462463

464+
flatErrors = {};
463465
state.errors = {};
464466
state.hasValidationErrors = false;
465467
state.valid = true;
@@ -480,14 +482,20 @@ const createManagerApi: CreateManagerApi = ({
480482
state.valid = false;
481483
state.invalid = true;
482484

485+
flatErrors = flatObject(errors);
486+
Object.keys(flatErrors).forEach((name) => {
487+
handleFieldError(name, false, flatErrors[name]);
488+
});
489+
483490
render();
484491
});
485492
}
486493

487494
const syncError = result as FormLevelError | undefined;
488495
if (syncError) {
489-
Object.keys(syncError).forEach((name) => {
490-
handleFieldError(name, false, syncError[name]);
496+
flatErrors = flatObject(syncError);
497+
Object.keys(flatErrors).forEach((name) => {
498+
handleFieldError(name, false, flatErrors[name]);
491499
});
492500
state.errors = syncError;
493501
state.hasValidationErrors = true;
@@ -499,6 +507,7 @@ const createManagerApi: CreateManagerApi = ({
499507
state.valid = true;
500508
state.invalid = false;
501509
state.error = undefined;
510+
flatErrors = {};
502511
/**
503512
* Fields have to be revalidated on field level to synchronize the form and field errors
504513
*/
@@ -872,15 +881,17 @@ const createManagerApi: CreateManagerApi = ({
872881
const render = prepareRerender();
873882

874883
if (error) {
875-
state.errors[name] = error;
884+
set(state.errors, name, error);
885+
flatErrors[name] = error;
876886
state.valid = false;
877887
state.invalid = true;
878888
state.hasValidationErrors = true;
879889
} else {
880-
delete state.errors[name];
890+
set(state.errors, name, undefined);
891+
delete flatErrors[name];
881892
}
882893

883-
if (Object.keys(state.errors).length === 0) {
894+
if (Object.keys(flatErrors).length === 0) {
884895
state.valid = true;
885896
state.invalid = false;
886897
state.hasValidationErrors = false;

0 commit comments

Comments
 (0)