最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How do I redirect to an edit page with the ID as a query parameter after form submission in Next.js? - Stack Overfl

programmeradmin1浏览0评论

I'm building a book management application using Next.js. I have a form that collects book details and submits them using an asynchronous function (onSubmit). The form data is sent to an action.ts file where it is validated and inserted into a Supabase database. After a successful submission, I want to redirect the user to an edit page while passing the ISBN of the newly submitted book in the URL.

  //submitting the forms
  async function onSubmit(data: BookInferSchema) {
    try {
      const formData = new FormData();
      Object.entries(data).forEach(([key, value]) => {
        formData.append(
          key,
          value instanceof Date ? value.toISOString() : value.toString()
        );
      });

      //sending the formData to the action.ts for submitting the forms
      const response = action(formData) as {
        error?: string;
        message?: string;
      } | void;

      //Error or success messages for any submissions and any errors/success from the server
      if (response?.error) {
        toast({
          title: "Error",
          description: `An error occurred: ${response.error}`,
        });
      } else {
        //after submitting the form, reset the form
        // form.reset();
      }
    } catch {
      toast({
        title: "Error",
        description: "An unexpected error occured.",
      });
    }
  }

And here’s a snippet of my action.ts where I validate and insert the book into the database:

const validatedFields = BookSchema.safeParse({
  ISBN: formData.get("ISBN"),
  //...other fields
});

if (!validatedFields.success) {
  console.error("Validation Errors:", validatedFields.error.format());
  return {
    errors: validatedFields.error.flatten().fieldErrors,
  };
}

const { ISBN } = validatedFields.data;

const supabase = createClient();
const { data, error } = await (await supabase)
  .from('books')
  .insert({
    isbn: ISBN,
    // ... other fields
  });

if (error) {
  return {
    error: true,
    message: error.message,
  };
}

return {
  error: false,
  message: 'Book updated successfully',
};

What I tried:

I tried returning the ISBN:

const successMessage = {
    error: false,
    message: "Book updated successfully",
    ISBN,
  };

return successMessage;

and use it here inside a !response?.error and it would just show as undefined when checking for the value of the response.

2nd try: I put this code in the action.ts after submissions:

// Perform the redirect after returning the success message
  redirect(`/admin/books/${ISBN}/edit`);

But it would show this an application error, and this is what the console would redirect me with:

This is the edit book page link: /admin/books/${id}/edit:

I am sure that I can access this page as I am also handling a redirect page for viewing each book.

const BookEdit = async (props: { params: Promise<{ id: string }> }) => {
  const supabase = await createClient();

  const {
    data: { user },
  } = await supabase.auth.getUser();

  if (!user) {
    return redirect("/login");
  }

  const params = await props.params;
  const id = params.id;

  const books = await fetchAllBooks(id);
  const bookData = books ? books[0] : null;

  return <h1>Edit Book {JSON.stringify(bookData, null, 2)}</h1>;
};

export default BookEdit;

3rd try: This worked, however, which is a better approach? should I put it inside the useEffect or just leave it ouside?

 useEffect(() => {
    if (state?.message) {
      toast({
        title: state?.error ? "Error" : "Success",
        description: state?.message,
      });
    }
  }, [state]);

  if (state?.id) {
    router.push(`/admin/books/${state.id}/edit`);
  }

I'm building a book management application using Next.js. I have a form that collects book details and submits them using an asynchronous function (onSubmit). The form data is sent to an action.ts file where it is validated and inserted into a Supabase database. After a successful submission, I want to redirect the user to an edit page while passing the ISBN of the newly submitted book in the URL.

  //submitting the forms
  async function onSubmit(data: BookInferSchema) {
    try {
      const formData = new FormData();
      Object.entries(data).forEach(([key, value]) => {
        formData.append(
          key,
          value instanceof Date ? value.toISOString() : value.toString()
        );
      });

      //sending the formData to the action.ts for submitting the forms
      const response = action(formData) as {
        error?: string;
        message?: string;
      } | void;

      //Error or success messages for any submissions and any errors/success from the server
      if (response?.error) {
        toast({
          title: "Error",
          description: `An error occurred: ${response.error}`,
        });
      } else {
        //after submitting the form, reset the form
        // form.reset();
      }
    } catch {
      toast({
        title: "Error",
        description: "An unexpected error occured.",
      });
    }
  }

And here’s a snippet of my action.ts where I validate and insert the book into the database:

const validatedFields = BookSchema.safeParse({
  ISBN: formData.get("ISBN"),
  //...other fields
});

if (!validatedFields.success) {
  console.error("Validation Errors:", validatedFields.error.format());
  return {
    errors: validatedFields.error.flatten().fieldErrors,
  };
}

const { ISBN } = validatedFields.data;

const supabase = createClient();
const { data, error } = await (await supabase)
  .from('books')
  .insert({
    isbn: ISBN,
    // ... other fields
  });

if (error) {
  return {
    error: true,
    message: error.message,
  };
}

return {
  error: false,
  message: 'Book updated successfully',
};

What I tried:

I tried returning the ISBN:

const successMessage = {
    error: false,
    message: "Book updated successfully",
    ISBN,
  };

return successMessage;

and use it here inside a !response?.error and it would just show as undefined when checking for the value of the response.

2nd try: I put this code in the action.ts after submissions:

// Perform the redirect after returning the success message
  redirect(`/admin/books/${ISBN}/edit`);

But it would show this an application error, and this is what the console would redirect me with: https://nextjs./docs/messages/sync-dynamic-apis

This is the edit book page link: /admin/books/${id}/edit:

I am sure that I can access this page as I am also handling a redirect page for viewing each book.

const BookEdit = async (props: { params: Promise<{ id: string }> }) => {
  const supabase = await createClient();

  const {
    data: { user },
  } = await supabase.auth.getUser();

  if (!user) {
    return redirect("/login");
  }

  const params = await props.params;
  const id = params.id;

  const books = await fetchAllBooks(id);
  const bookData = books ? books[0] : null;

  return <h1>Edit Book {JSON.stringify(bookData, null, 2)}</h1>;
};

export default BookEdit;

3rd try: This worked, however, which is a better approach? should I put it inside the useEffect or just leave it ouside?

 useEffect(() => {
    if (state?.message) {
      toast({
        title: state?.error ? "Error" : "Success",
        description: state?.message,
      });
    }
  }, [state]);

  if (state?.id) {
    router.push(`/admin/books/${state.id}/edit`);
  }
Share Improve this question edited Mar 15 at 5:56 JS3 asked Mar 15 at 4:33 JS3JS3 1,8694 gold badges34 silver badges83 bronze badges 1
  • i would begin by doing a bit more research on your first attempt. Surely there's a reason whatever process you are returning to is ignoring the extra property you set. – Kevin B Commented Mar 15 at 4:42
Add a comment  | 

1 Answer 1

Reset to default 0

In your action.ts file, try selecting data from supabase after .insert()

const { ISBN } = validatedFields.data;

const supabase = createClient();
const { data, error } = await supabase
  .from('books')
  .insert({ isbn: ISBN })
  .select()


if (error) {
  return {
    error: true,
    message: error.message
  };
}

return {
  error: false,
  message: 'Book updated successfully',
  data
};

Supabase Docs : Here

You can then use useRouter (If Client Component) or redirect from next/navigation and route the user to the edit page by getting data from response.

Next.Js Routing Docs: Here

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论