diff --git a/examples/react/next-server-actions/src/app/action.ts b/examples/react/next-server-actions/src/app/action.ts
index 8ffa3fc02..03154ec75 100644
--- a/examples/react/next-server-actions/src/app/action.ts
+++ b/examples/react/next-server-actions/src/app/action.ts
@@ -9,9 +9,13 @@ import { formOpts } from './shared-code'
const serverValidate = createServerValidate({
...formOpts,
onServerValidate: ({ value }) => {
- if (value.age < 12) {
- return 'Server validation: You must be at least 12 to sign up'
- }
+ if (value.age < 12)
+ return {
+ fields: {
+ age: 'Server validation: You must be at least 12 to sign up',
+ },
+ form: 'Form level Error: Age must be at least 12',
+ }
},
})
diff --git a/examples/react/next-server-actions/src/app/client-component.tsx b/examples/react/next-server-actions/src/app/client-component.tsx
index b7e62909c..a7104e555 100644
--- a/examples/react/next-server-actions/src/app/client-component.tsx
+++ b/examples/react/next-server-actions/src/app/client-component.tsx
@@ -3,7 +3,6 @@
import { useActionState } from 'react'
import { mergeForm, useForm, useTransform } from '@tanstack/react-form'
import { initialFormState } from '@tanstack/react-form/nextjs'
-import { useStore } from '@tanstack/react-store'
import someAction from './action'
import { formOpts } from './shared-code'
@@ -18,14 +17,8 @@ export const ClientComp = () => {
),
})
- const formErrors = useStore(form.store, (formState) => formState.errors)
-
return (
+ | undefined
+
+ if (!serverErrorMap) return state
+
+ batch(() => {
+ void (Object.values(this.fieldInfo) as FieldInfo[]).forEach(
+ (field) => {
+ const fieldInstance = field.instance
+
+ if (!fieldInstance) return
+
+ if (fieldInstance.name in serverErrorMap) {
+ fieldInstance.setMeta((prev) => ({
+ ...prev,
+ errorMap: {
+ ...prev.errorMap,
+ onServer: serverErrorMap[fieldInstance.name],
+ },
+ }))
+ fieldInstance.mount()
+ }
+
+ this.validateField(fieldInstance.name, 'server')
+ },
+ )
+ })
}
return state
@@ -1503,6 +1532,20 @@ export class FormApi<
},
}))
}
+
+ /**
+ * when we have an error for onServer in the state, we want
+ * to clear the error as soon as the user changes the value in the field
+ */
+ if (cause !== 'server') {
+ this.baseStore.setState((prev) => ({
+ ...prev,
+ errorMap: {
+ ...prev.errorMap,
+ onServer: undefined,
+ },
+ }))
+ }
})
return { hasErrored, fieldsErrorMap: currentValidationErrorMap }
@@ -1925,6 +1968,7 @@ export class FormApi<
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
...prev?.errorMap,
onMount: undefined,
+ onServer: undefined,
},
}))
}
diff --git a/packages/react-form/src/nextjs/createServerValidate.ts b/packages/react-form/src/nextjs/createServerValidate.ts
index adaa4de1f..fc1bdaaae 100644
--- a/packages/react-form/src/nextjs/createServerValidate.ts
+++ b/packages/react-form/src/nextjs/createServerValidate.ts
@@ -96,20 +96,41 @@ export const createServerValidate =
validationSource: 'form',
})) as UnwrapFormAsyncValidateOrFn | undefined
+ console.log('ON SERVER ERROR', onServerError)
+
if (!onServerError) return values
- const onServerErrorVal = (
- isGlobalFormValidationError(onServerError)
- ? onServerError.form
- : onServerError
- ) as UnwrapFormAsyncValidateOrFn
+ let onServerErrorVal = undefined
+ let onServerErrorValFields = undefined
+
+ if (isGlobalFormValidationError(onServerError)) {
+ onServerErrorVal =
+ onServerError.form as UnwrapFormAsyncValidateOrFn
+ onServerErrorValFields =
+ onServerError.fields as UnwrapFormAsyncValidateOrFn
+ } else {
+ onServerErrorVal = onServerError as UnwrapFormAsyncValidateOrFn
+ }
+
+ // Extract string values from errors if they're in object format
+ const errorsArray = onServerErrorVal
+ ? Array.isArray(onServerErrorVal)
+ ? onServerErrorVal.map((err) =>
+ typeof err === 'object' ? Object.values(err)[0] : err,
+ )
+ : [
+ typeof onServerErrorVal === 'object'
+ ? Object.values(onServerErrorVal)[0]
+ : onServerErrorVal,
+ ]
+ : []
const formState: ServerFormState = {
errorMap: {
- onServer: onServerError,
+ onServer: onServerErrorValFields,
},
values,
- errors: onServerErrorVal ? [onServerErrorVal] : [],
+ errors: errorsArray,
}
throw new ServerValidateError({