Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to add validation errors manually? #813

Open
stabildev opened this issue Oct 30, 2024 · 6 comments
Open

How to add validation errors manually? #813

stabildev opened this issue Oct 30, 2024 · 6 comments

Comments

@stabildev
Copy link

Describe the bug and the expected behavior

I am biting my teeth out with this.

Looking for a way to add validation errors manually like fields.email.errors.push("Invalid email")

Also tried submission.reply in onSubmit, to no effect:

const [form, fields] = useForm<CreateUserInput>({
    shouldValidate: "onSubmit",
    shouldRevalidate: "onInput",
    onValidate: ({ formData }) => parseWithZod(formData, { schema: createUserSchema }),
    onSubmit: (e, { submission }) => {
      e.preventDefault();
      if (submission?.status !== "success") return;
      try {
        await createUser(submission.value);
      } catch (e) {
        return { ...submission, errors: { email: ["Invalid email"] } }
    },
  });

I am not using server actions.

Conform version

1.1.5

Steps to Reproduce the Bug or Issue

const [form, fields] = useForm<CreateUserInput>({
    shouldValidate: "onSubmit",
    shouldRevalidate: "onInput",
    onValidate: ({ formData }) => parseWithZod(formData, { schema: createUserSchema }),
    onSubmit: (e, { submission }) => {
      e.preventDefault();
      if (submission?.status !== "success") return;
      try {
        await createUser(submission.value);
      } catch (e) {
        return { ...submission, errors: { email: ["Invalid email"] } }
    },
  });

What browsers are you seeing the problem on?

No response

Screenshots or Videos

No response

Additional context

No response

@juanpmarin
Copy link

@stabildev ¿are you using nextjs?

@stabildev
Copy link
Author

@stabildev ¿are you using nextjs?

Yes

@juanpmarin
Copy link

juanpmarin commented Oct 31, 2024

The way you pass errors from the backend to the form, is trough lastResult property, which you're not using.

Try something like:

action.ts file

"use server";

import { parseWithZod } from "@conform-to/zod";
import { verifyOtpSchema } from "./schema";

export async function myServerAction(_: unknown, formData: FormData) {
  const submission = parseWithZod(formData, {
    schema: verifyOtpSchema,
  });

  if (submission.status !== "success") {
    return submission.reply();
  }

  return submission.reply({
      fieldErrors: {
        name: ["my custom error"],
      },
    });
}

IMPORTANT!

Don't call the server action in the onSubmit function manually, instead use useActionState and pass the action property to the form. It's the most ergonomic way, and handles lastResult for you

form.tsx

"use client";

import { getFormProps, getInputProps, useForm } from "@conform-to/react";
import { parseWithZod } from "@conform-to/zod";
import { useActionState } from "react";
import { verify } from "./action";
import { mySchema } from "./schema";

export function MyForm() {
  const [lastResult, action] = useActionState(myServerAction, undefined);
  const [form, fields] = useForm({
    lastResult,
    onValidate({ formData }) {
      return parseWithZod(formData, {
        schema: mySchema,
      });
    },
  });

  return (
    <form {...getFormProps(form)} action={action}>
      <div>
        <input {...getInputProps(fields.name, { type: "text" })} />
        {fields.name.errors && <p>{fields.name.errors}</p>}
      </div>

      <button type="submit">Submit</button>
    </form>
  );
}

@stabildev
Copy link
Author

As I said, I am not using server actions (at all)

@edmundhung
Copy link
Owner

const [lastResult, setLastResult] = useState();
const [form, fields] = useForm<CreateUserInput>({
    lastResult,
    shouldValidate: "onSubmit",
    shouldRevalidate: "onInput",
    onValidate: ({ formData }) => parseWithZod(formData, { schema: createUserSchema }),
    onSubmit: (e, { submission }) => {
      e.preventDefault();
      if (submission?.status !== "success") return;
      try {
        await createUser(submission.value);
      } catch (e) {
        setLastResult(submission.reply({ fieldsErrors: { email: ["Invalid email"] } }));
    },
});

@juanpmarin
Copy link

Right :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants