Replies: 1 comment
-
Solved using a couple of helper functions: "use client";
import type { AnyFormApi } from "@tanstack/react-form";
import type { ZodIssue } from "zod";
/**
* Add the server-side validation errors to the form.
*/
export function addServerSideValidationErrorsToForm<T>(
form: AnyFormApi,
errors: ZodIssue[],
) {
const errorMap = new Map<string, string[]>();
for (const error of errors) {
// we don't know if this is correct or not, but it works for top-level object fields
const path = error.path.join(".");
const errorMessages = errorMap.get(path) ?? [];
errorMessages.push(error.message);
errorMap.set(path, errorMessages);
}
for (const [path, errorMessages] of errorMap.entries()) {
form.setFieldMeta(path, (prev) => {
return { ...prev, errorMap: { onServer: errorMessages.join(", ") } };
});
}
} "use client";
import type { AnyFieldApi, StandardSchemaV1Issue } from "@tanstack/react-form";
import { useStore } from "@tanstack/react-form";
/**
* Displays the status of a field.
*
* The Standard Schema is compatible with Standard Schema validation libraries such as Zod.
*
* @see https://github.com/standard-schema/standard-schema
*/
export function FieldStatus({ field }: { field: AnyFieldApi }) {
const submissionAttempts = useStore(
field.form.store,
(state) => state.submissionAttempts,
);
const errorz = useStore(
field.form.store,
(state) => state.fieldMeta[field.name]?.errorMap?.onServer,
);
let errorMessage = "";
const validate = submissionAttempts > 0 || field.state.meta.isTouched;
if (validate && field.state.meta.errors.length > 0) {
const errors = field.state.meta.errors as StandardSchemaV1Issue[];
errorMessage = errors.map((error) => error.message).join(", ");
}
return (
<>
{errorMessage && (
<div className="mt-1 text-sm text-red-600">{errorMessage}</div>
)}
{typeof errorz === "string" && Boolean(errorz) && (
<div className="mt-1 text-sm text-red-600">{errorz}</div>
)}
{field.state.meta.isValidating && (
<div className="mt-1 text-sm text-gray-600">Validating...</div>
)}
</>
);
} Then the server function can just return the zod issues to the client: // React Server Function is just a normal POST, so the data still needs to be validated
// we can use the same zod schema for both client and server validation!
const { error } = await createOrganizationUserSchema.safeParseAsync(data);
if (error) {
return {
errorz: error.errors,
};
} const { errorz } = await createOrganizationUser(data);
if (errorz) {
addServerSideValidationErrorsToForm(form, errorz);
throw new Error("Failed to create user");
} That said, it would be nice if propagating server error back to the form is seamless. |
Beta Was this translation helpful? Give feedback.
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
-
Thank you for creating this library.
I believe simpler error management for server-side errors would be appreciated.
I've been spending hours trying to set additional error message after submission using
setFieldMeta
orform.setErrorMap
to no success.I would appreciate it if we can have an API like:
I am getting an array of
ZodIssue
from the server and I would like to be able to iterate through the array and just add the errors manually to the form.Thank you.
Beta Was this translation helpful? Give feedback.
All reactions