From bf17c91b05c7217463421a7468503ec487e0f77d Mon Sep 17 00:00:00 2001
From: Ogura Daiki <8hachibee125@gmail.com>
Date: Wed, 21 Feb 2024 10:13:07 +0900
Subject: [PATCH] improve [handleSubmit] to able to handle return value
---
src/index.test.tsx | 66 +++++++++++++++++++++++++++++++++++++++++++++-
src/index.ts | 30 +++++++++++++--------
2 files changed, 84 insertions(+), 12 deletions(-)
diff --git a/src/index.test.tsx b/src/index.test.tsx
index 5f2fb51..9e98104 100644
--- a/src/index.test.tsx
+++ b/src/index.test.tsx
@@ -90,13 +90,20 @@ test('zod parse value before submit', async () => {
} else {
expect('should not called').toBe(result.error);
}
+ return Promise.resolve('returns value');
});
const Top = () => {
return (
-
+
);
};
@@ -123,6 +130,63 @@ test('zod parse value before submit', async () => {
});
});
+test('able to handle parse error on submit', async () => {
+ const TestFormHook = createTestHook();
+
+ const INPUT_AGE = 'aaaa';
+ const EXPECTED_ISSUE = {
+ code: 'custom',
+ message: 'Invalid input',
+ path: ['age'],
+ };
+
+ const handleSubmitTester = TestFormHook.handleSubmit((e) => (result) => {
+ if (result.success) {
+ expect('should not succeed').toBe(false);
+ } else {
+ expect(result.success).toBe(false);
+ expect(result.error).toStrictEqual([EXPECTED_ISSUE]);
+ }
+ return Promise.resolve('returns value');
+ });
+
+ const Top = () => {
+ return (
+
+
+
+ );
+ };
+
+ render();
+
+ const ageInput: HTMLInputElement = screen.getByTestId('age-input');
+ await userEvent.type(ageInput, INPUT_AGE);
+
+ await waitFor(() => {
+ const ageInput: HTMLInputElement = screen.getByTestId('age-input');
+ expect(ageInput.value).toBe(INPUT_AGE);
+ });
+
+ const submitButton = screen.getByTestId('submit-button');
+ await userEvent.click(submitButton);
+
+ await waitFor(() => {
+ console.log('waiting');
+ TestFormHook.api.actions.peek((s) => {
+ expect(s.value.age).toBe(INPUT_AGE);
+ expect(s.errors.age).toBe(EXPECTED_ISSUE.message);
+ });
+ });
+});
+
test('User is able to re-initialize the form state', async () => {
const TestFormHook = createTestHook();
diff --git a/src/index.ts b/src/index.ts
index 9b600f9..b54cf6e 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -249,13 +249,11 @@ export type Controller = {
type FormHook> = {
controller: Controller;
- handleSubmit: (
+ handleSubmit: (
handler: (
e: BaseSyntheticEvent,
- ) => (
- val: {success: true; data: zodInfer; error: undefined} | {success: false; error: ReadonlyArray},
- ) => void | Promise,
- ) => (e: BaseSyntheticEvent) => void;
+ ) => (val: {success: true; data: zodInfer; error: undefined} | {success: false; error: ReadonlyArray}) => R,
+ ) => (e: BaseSyntheticEvent) => Promise;
api: Subscriber, FormControllerBehavior>;
} & Controller;
@@ -276,12 +274,10 @@ export function createFormHook(
handler: (
e: BaseSyntheticEvent,
- ) => (
- val: {success: true; data: zodInfer; error: undefined} | {success: false; error: ReadonlyArray},
- ) => void | Promise,
+ ) => (val: {success: true; data: zodInfer; error: undefined} | {success: false; error: ReadonlyArray}) => R,
) => {
return (e: BaseSyntheticEvent) => {
const eventHandled = handler(e);
@@ -292,8 +288,20 @@ export function createFormHook {
+ store.actions.handleIssues(result.error.issues);
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-return
+ return x;
+ }) as R;
+ } else {
+ store.actions.handleIssues(result.error.issues);
+ return handled as R;
+ }
});
};
},