Next.js Discord

Discord Forum

Server Action: last item in list is not returning message

Unanswered
Plott Hound posted this in #help-forum
Open in Discord
Avatar
Plott HoundOP
im fetching a list of tasks with prisma and using server actions to add/delete them. it all works but i noticed a strange issue where im not receiving the state message back when i try to delete the last one in the list or the only item, the item gets deleted but there is no message returned.

Action:
export async function handleDeleteTask(prevState: any, formData: FormData) {

    const DeleteTaskSchema = z.object({
        taskId: z.string().min(1),
        boardId: z.string().min(1),
    });

    const data = DeleteTaskSchema.parse({
        taskId: formData.get('taskId') as string,
        boardId: formData.get('boardId') as string,
    })

    try {
        await prisma.task.delete({
            where: {
                id: data.taskId,
            }
        });

        revalidatePath(`/board/${data.boardId}`);

        return { 
            success: true,
            message: `Deleted task`,
        }
    } catch (e) {
        return { 
            success: false,
            message: 'Failed to delete task'
        }
    }
}

2 Replies

Avatar
Plott HoundOP
form:
'use client'

import { useFormState, useFormStatus } from "react-dom";
import { useEffect } from "react";
import { handleDeleteTask} from "@/actions/TaskActions";
import { IconTrash } from "@tabler/icons-react";
import toast from "react-hot-toast";

function DeleteButton() {
  const { pending } = useFormStatus()

  return (
    <button 
      type="submit" 
      aria-disabled={pending}
      className="ml-1"
    >
      <IconTrash size={18} />
    </button>
  )
}

export default function DeleteTaskForm({ boardId, taskId, taskTitle }: { boardId: string; taskId: string; taskTitle: string; }) {
  const [state, formAction] = useFormState(handleDeleteTask, null)

  useEffect(() => {
    if (state?.success) {
      toast.success(state.message);
    } else if (state?.success === false) {
      toast.error(state.message);
    }
  }, [state?.success, state?.message]);

  return (
    <>
    <form 
      action={formAction}
      className="leading-none"
      onSubmit={(e) => {
        e.preventDefault();
        const confimed = confirm("Are you sure you want to delete this task?");
        if (confimed) {
          formAction(new FormData(e.currentTarget));
        }
      }}
    >
      <input type="hidden" name="boardId" value={boardId} />
      <input type="hidden" name="taskId" value={taskId} />
      <DeleteButton />
      <p aria-live="polite" className="sr-only" role="status">
        {state?.message}
      </p>
    </form>
    </>
  )
}
Avatar
Plott HoundOP
bump