Skip to content
This repository has been archived by the owner on Dec 27, 2022. It is now read-only.

Commit

Permalink
feat: introduce onRawSubmit and parseSubmitException
Browse files Browse the repository at this point in the history
  • Loading branch information
chambo-e committed Mar 15, 2022
1 parent aa99a59 commit 83eb81e
Show file tree
Hide file tree
Showing 6 changed files with 123 additions and 4 deletions.
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,8 @@
"final-form": "4.20.6",
"final-form-arrays": "3.0.2",
"final-form-focus": "1.1.2",
"react-final-form": "6.5.8"
"react-final-form": "6.5.8",
"react-final-form-arrays": "3.1.3"
},
"dependenciesMeta": {
"@react-spring/core": {
Expand Down
28 changes: 28 additions & 0 deletions src/components/Form/__tests__/__snapshots__/index.spec.tsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,20 @@ exports[`Form renders correctly with node children 1`] = `
</DocumentFragment>
`;

exports[`Form renders correctly with onRawSubmit which should take precedence 1`] = `
<DocumentFragment>
<form
novalidate=""
>
<button
type="submit"
>
Submit
</button>
</form>
</DocumentFragment>
`;

exports[`Form renders correctly with onSubmit that return {} 1`] = `
<DocumentFragment>
<form
Expand Down Expand Up @@ -62,6 +76,20 @@ exports[`Form renders correctly with onSubmit that throw 1`] = `
</DocumentFragment>
`;

exports[`Form renders correctly with parseSubmitException 1`] = `
<DocumentFragment>
<form
novalidate=""
>
<button
type="submit"
>
Submit
</button>
</form>
</DocumentFragment>
`;

exports[`Form renders correctly with validate 1`] = `
<DocumentFragment>
<form
Expand Down
59 changes: 59 additions & 0 deletions src/components/Form/__tests__/index.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -92,4 +92,63 @@ describe('Form', () => {
},
)
})

test('renders correctly with parseSubmitException', () => {
const onSubmit = jest.fn(() => Promise.reject(new Error('error')))
const onSubmitSuccess = jest.fn(() => {})
const onSubmitError = jest.fn(() => {})
const parseSubmitException = jest.fn(() => 'parsed error')

return shouldMatchEmotionSnapshot(
<Form
errors={mockErrors}
onSubmitSuccess={onSubmitSuccess}
onSubmit={onSubmit}
onSubmitError={onSubmitError}
parseSubmitException={parseSubmitException}
>
<button type="submit">Submit</button>
</Form>,
{
transform: async ({ getByText }) => {
userEvent.click(getByText('Submit'))
expect(onSubmit).toBeCalledTimes(1)
await waitFor(() => expect(onSubmitError).toBeCalledTimes(1))
await waitFor(() => expect(parseSubmitException).toBeCalledTimes(1))
expect(parseSubmitException).toBeCalledWith(new Error('error'))
expect(onSubmitSuccess).toBeCalledTimes(0)
},
},
)
})

test('renders correctly with onRawSubmit which should take precedence', () => {
const onSubmit = jest.fn(() => Promise.reject(new Error('error')))
const onSubmitSuccess = jest.fn(() => {})
const onRawSubmit = jest.fn(() => {})
const onSubmitError = jest.fn(() => {})
const parseSubmitException = jest.fn(() => 'parsed error')

return shouldMatchEmotionSnapshot(
<Form
errors={mockErrors}
onSubmitSuccess={onSubmitSuccess}
onSubmit={onSubmit}
onSubmitError={onSubmitError}
parseSubmitException={parseSubmitException}
onRawSubmit={onRawSubmit}
>
<button type="submit">Submit</button>
</Form>,
{
transform: async ({ getByText }) => {
userEvent.click(getByText('Submit'))
await waitFor(() => expect(onRawSubmit).toBeCalledTimes(1))
expect(onSubmit).toBeCalledTimes(0)
expect(onSubmitError).toBeCalledTimes(0)
expect(parseSubmitException).toBeCalledTimes(0)
},
},
)
})
})
18 changes: 16 additions & 2 deletions src/components/Form/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export type FormProps<FormValues = unknown> = {
| ((props: FormRenderProps<FormValues, Partial<FormValues>>) => ReactNode)
| ReactNode
errors: FormErrors
onRawSubmit?: ReactFinalFormProps<FormValues, Partial<FormValues>>['onSubmit']
onSubmit?: ReactFinalFormProps<FormValues, Partial<FormValues>>['onSubmit']
onSubmitSuccess?: OnSubmitSucccessFn<FormValues>
onSubmitError?: OnSubmitErrorFn
Expand All @@ -33,9 +34,11 @@ export type FormProps<FormValues = unknown> = {
render?: ReactFinalFormProps<FormValues, Partial<FormValues>>['render']
mutators?: ReactFinalFormProps<FormValues, Partial<FormValues>>['mutators']
keepDirtyOnReinitialize?: boolean
parseSubmitException?: (error: unknown) => string | undefined
}
const Form = <FormValues,>({
children,
onRawSubmit,
onSubmit,
onSubmitError,
onSubmitSuccess,
Expand All @@ -47,18 +50,25 @@ const Form = <FormValues,>({
render,
mutators,
keepDirtyOnReinitialize,
parseSubmitException,
}: FormProps<FormValues>): JSX.Element => (
<ErrorProvider errors={errors}>
<ReactFinalForm
initialValues={initialValues}
validateOnBlur={validateOnBlur}
validate={validate}
decorators={[focusOnErrors as unknown as Decorator<FormValues, Partial<FormValues>>]}
decorators={[
focusOnErrors as unknown as Decorator<FormValues, Partial<FormValues>>,
]}
mutators={{
...arrayMutators,
...mutators,
}}
onSubmit={async (values, form, callback) => {
if (onRawSubmit) {
return onRawSubmit(values, form, callback)
}

try {
const res = await onSubmit?.(values, form, callback)
if (res !== undefined) {
Expand All @@ -71,7 +81,11 @@ const Form = <FormValues,>({
} catch (submitError) {
await onSubmitError?.(submitError)

return { [FORM_ERROR]: submitError }
return {
[FORM_ERROR]: parseSubmitException
? parseSubmitException(submitError)
: submitError,
}
}
}}
render={
Expand Down
2 changes: 2 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,5 @@ export { default as SwitchField } from './components/SwitchField'
export { default as TagsField } from './components/TagsField'
export { default as TextBoxField } from './components/TextBoxField'
export type { FormErrors } from './types'
export { FormSpy, useFormState, useForm, useField } from 'react-final-form'
export { FieldArray, useFieldArray } from 'react-final-form-arrays'
17 changes: 16 additions & 1 deletion yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1538,7 +1538,7 @@ __metadata:
languageName: node
linkType: hard

"@babel/runtime@npm:7.17.2":
"@babel/runtime@npm:7.17.2, @babel/runtime@npm:^7.12.1":
version: 7.17.2
resolution: "@babel/runtime@npm:7.17.2"
dependencies:
Expand Down Expand Up @@ -3360,6 +3360,7 @@ __metadata:
react: 17.0.2
react-dom: 17.0.2
react-final-form: 6.5.8
react-final-form-arrays: 3.1.3
read-pkg: 7.1.0
regenerator-runtime: 0.13.9
rollup: 2.70.1
Expand Down Expand Up @@ -16894,6 +16895,20 @@ __metadata:
languageName: node
linkType: hard

"react-final-form-arrays@npm:3.1.3":
version: 3.1.3
resolution: "react-final-form-arrays@npm:3.1.3"
dependencies:
"@babel/runtime": ^7.12.1
peerDependencies:
final-form: ^4.15.0
final-form-arrays: ">=1.0.4"
react: ^16.8.0 || ^17.0.0
react-final-form: ^6.2.1
checksum: 1881244afe4e752d238e268e82ae899884abe830ce09c8f14ffb0a28830526b60cffcd0dcbb9202380f582d4e7f413ea97fcb1d4c4fd5aa434dd7c1d1c2cc722
languageName: node
linkType: hard

"react-final-form@npm:6.5.8":
version: 6.5.8
resolution: "react-final-form@npm:6.5.8"
Expand Down

0 comments on commit 83eb81e

Please sign in to comment.