Skip to content

Commit fd78461

Browse files
authored
Better fix for async error bug (#441)
* Better fix for async error bug * Lowered delay in test * Raised delay on async test
1 parent 69fcae5 commit fd78461

3 files changed

Lines changed: 22 additions & 16 deletions

File tree

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@
9393
},
9494
{
9595
"path": "dist/final-form.cjs.js",
96-
"maxSize": "10.0kB"
96+
"maxSize": "10.1kB"
9797
}
9898
],
9999
"dependencies": {

src/FinalForm.js

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -417,12 +417,13 @@ function createForm<FormValues: FormValuesShape>(
417417
asyncValidationPromises[asyncValidationPromiseKey] = promise;
418418
}
419419

420-
const processErrors = () => {
420+
const processErrors = (afterAsync: boolean) => {
421421
let merged = {
422422
...(limitedFieldLevelValidation ? formState.errors : {}),
423423
...recordLevelErrors,
424-
...formState.asyncErrors, // previous async errors
425-
...asyncRecordLevelErrors, // new async errors
424+
...(afterAsync
425+
? asyncRecordLevelErrors // new async errors
426+
: formState.asyncErrors), // previous async errors
426427
};
427428
const forEachError = (fn: (name: string, error: any) => void) => {
428429
fieldKeys.forEach((name) => {
@@ -460,7 +461,9 @@ function createForm<FormValues: FormValuesShape>(
460461
if (!shallowEqual(formState.errors, merged)) {
461462
formState.errors = merged;
462463
}
463-
formState.asyncErrors = asyncRecordLevelErrors;
464+
if (afterAsync) {
465+
formState.asyncErrors = asyncRecordLevelErrors;
466+
}
464467
formState.error = recordLevelErrors[FORM_ERROR];
465468
};
466469

@@ -471,7 +474,7 @@ function createForm<FormValues: FormValuesShape>(
471474
}
472475

473476
// process sync errors
474-
processErrors();
477+
processErrors(false);
475478
// sync errors have been set. notify listeners while we wait for others
476479
callback();
477480

@@ -488,7 +491,7 @@ function createForm<FormValues: FormValuesShape>(
488491
return;
489492
}
490493

491-
processErrors();
494+
processErrors(true);
492495
})
493496
.then(afterPromise, afterPromise);
494497
}

src/FinalForm.validating.test.js

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -348,7 +348,7 @@ describe("Field.validation", () => {
348348
});
349349

350350
it("should allow record-level async validation via promises", async () => {
351-
const delay = 2;
351+
const delay = 10;
352352
const form = createForm({
353353
onSubmit: onSubmitMock,
354354
validate: async (values) => {
@@ -393,19 +393,20 @@ describe("Field.validation", () => {
393393

394394
change("another");
395395

396-
// spy called because sync validation passed
397-
expect(spy).toHaveBeenCalledTimes(3);
398-
expect(spy.mock.calls[2][0].error).toBeUndefined();
396+
await sleep(delay / 2);
397+
398+
// spy not called because async validation not yet done
399+
expect(spy).toHaveBeenCalledTimes(2);
399400

400-
// wait for validation to return
401401
await sleep(delay * 2);
402402

403-
// spy not called because sync validation already cleared error
403+
// spy called because async validation completed
404404
expect(spy).toHaveBeenCalledTimes(3);
405+
expect(spy.mock.calls[2][0].error).toBeUndefined();
405406
});
406407

407-
it.only("should not reset record-level async validation results until they have been replaced", async () => {
408-
const delay = 50;
408+
it("should not reset record-level async validation results until they have been replaced", async () => {
409+
const delay = 10;
409410
const form = createForm({
410411
onSubmit: onSubmitMock,
411412
validate: async (values) => {
@@ -441,6 +442,8 @@ describe("Field.validation", () => {
441442
expect(spy.mock.calls[1][0].error).toBe("Username taken");
442443

443444
change("erikrasm"); // too long
445+
change("erikrasmu"); // too long
446+
change("erikrasmus"); // too long
444447

445448
await sleep(delay / 2);
446449

@@ -464,7 +467,7 @@ describe("Field.validation", () => {
464467
// wait for validation to return
465468
await sleep(delay * 2);
466469

467-
// spy called because sync validation passed
470+
// spy called because async validation passed
468471
expect(spy).toHaveBeenCalledTimes(4);
469472
expect(spy.mock.calls[3][0].error).toBeUndefined();
470473

0 commit comments

Comments
 (0)