3

I am trying to add the functionality to create annd delete a Prisma record from within my component. My router has no errors just getting type errors in my component.

Errors exist at { title, content, assigneeId } } and { id: id } in the create and delete task mutations

Argument of type '{ input: { title: string; content: string; assigneeId: string; }; }' is not assignable to parameter of type 'void'.ts(2345)

Argument of type '{ id: string; }' is not assignable to parameter of type 'void'.ts(2345)

Tasks.ts

import { z } from "zod";

export const TaskCreateInput = z.object({
  title: z.string(),
  content: z.string(),
  assigneeId: z.string(),
});
export const TaskDeleteInput = z.object({
  id: z.string(),
});

import {
    createTRPCRouter,
    publicProcedure,
  } from "~/server/api/trpc";

  export const tasksRouter = createTRPCRouter({
    getAll: publicProcedure.query(({ ctx }) => {
      return ctx.prisma.task.findMany();
    }),  
    createTask: publicProcedure.mutation(({ ctx, input }) => {
      const validatedInput = TaskCreateInput.parse(input);
      return ctx.prisma.task.create({
        data: validatedInput,
      });
    }),
    deleteTask: publicProcedure.mutation(({ ctx, input }) => {
      const validatedInput = TaskDeleteInput.parse(input);
      return ctx.prisma.task.delete({
        where: {
          id: validatedInput.id,
        },
      });
    }),
  });

Maintenance.tsx

import React, {useState } from "react";

import { api } from "~/utils/api";
import type { TaskCreateInput, TaskDeleteInput } from "~/server/api/routers/tasks";

const Maintenance = () => {
  const { data } = api.tasks.getAll.useQuery();
  const createTaskMutation = api.tasks.createTask.useMutation();
  const deleteTaskMutation = api.tasks.deleteTask.useMutation();

  const [title, setTitle] = useState("");
    const [content, setContent] = useState("");
    const [assigneeId, setAssigneeId] = useState("");

    const handleCreateTask = () => {
        createTaskMutation.mutate({ input: { title, content, assigneeId } }, {
          onSuccess: () => {
            setTitle("");
            setContent("");
            setAssigneeId("");
          },
        });
      };
      const handleDeleteTask = (id: string) => {
        deleteTaskMutation.mutate({ id: id }, {
          onSuccess: () => {
            // handle success
          },
        });
      };

  return (
    <> 
    <div className="mb-4">
        <input className="mr-2" type="text" placeholder="Title" value={title} onChange={(e) => setTitle(e.target.value)}/>
        <input className="mr-2" type="text" placeholder="Content" value={content} onChange={(e) => setContent(e.target.value)}/>
        <input className="mr-2" type="text" placeholder="Asignee" value={assigneeId} onChange={(e) => setAssigneeId(e.target.value)}/>
        <button className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded" onClick={handleCreateTask}>
            Add Task
        </button>
    </div>

      {data?.map((task) => (
        <div key={task.id} className="max-w-sm rounded overflow-hidden shadow-lg mb-4 flex flex-row bg-red-500">
          <div className="px-6 py-4">
            <div className="font-bold text-xl mb-2">{task.title}</div>
            <p className="font-light text=gray-700 text-base">{task.content}</p>
            <h2>Assigned to: {task.assigneeId}</h2>
          </div>
          <button className="bg-red-500 hover:bg-red-700 text-white font-bold py-2 px-4 rounded" onClick={() => handleDeleteTask(task.id)}>
            Delete
          </button>
        </div>
      ))}
    </>
  );
};

export default Maintenance;

1 Answers1

0

I think you're missing the input method on your procedure. This is where you can validate your input.

{
  createTask: publicProcedure
    .input(TaskCreateInput)
    .mutation(({ ctx, input }) => {
      return ctx.prisma.task.create({
        data: input,
      });
    }),
};

Now in your handleCreateTask you can remove the input object and simply pass a object with the expected values.

const handleCreateTask = () => {
  createTaskMutation.mutate(
    { title, content, assigneeId },
    {
      onSuccess: () => {
        setTitle("");
        setContent("");
        setAssigneeId("");
      },
    }
  );
};

Same principle for deleteTask

RubenSmn
  • 4,091
  • 2
  • 5
  • 24