I’m making an app in nextjs to practice, and I am having a hard time getting single data to delete from the database using the findByIdAndDelete function.
CastError: Cast to ObjectId failed for value "undefined" (type string) at path "_id" for model "Appointment"
./page.jsx
import AddAppointment from "./addAppointment";
import DeleteAppointment from "./deleteAppointment";
import UpdateAppointment from "./updateAppointment";
async function getAppointment() {
const res = await fetch("http://localhost:3000/api/appointment", {
method: "GET",
cache: "no-store",
});
// const data = await res.json();
return res.json();
}
async function Appointment() {
const { appointment } = await getAppointment();
return (
<div className="py-10 px-10">
<div className="py-2">
<AddAppointment />
</div>
<table className="table w-full">
<thead>
<tr>
<th>#</th>
<th>Nama</th>
<th>Tanggal</th>
<th>No Telp.</th>
<th>Terapis</th>
<th>Status</th>
<th>Action</th>
</tr>
</thead>
<tbody>
{appointment.map((row, i) => (
<tr key={row._id}>
<td>{i + 1}</td>
<td>{row.name}</td>
<td>{row.date}</td>
<td>{row.phone}</td>
<td>{row.terapist}</td>
<td>{row.statust || "unknown"}</td>
<td className="flex">
<UpdateAppointment {...appointment} />
<DeleteAppointment {...appointment} />
</td>
</tr>
))}
</tbody>
</table>
</div>
);
}
export default Appointment;
./deleteAppointment.jsx
"use client";
import { useState } from "react";
import { useRouter } from "next/navigation";
export default function DeleteAppointment() {
const [modal, setModal] = useState(false);
const router = useRouter();
async function handleDelete({ id }) {
await fetch(`http://localhost:3000/api/appointment?id=${id}`, {
method: "DELETE",
});
router.refresh();
setModal(false);
}
function handleChange() {
setModal(!modal);
}
return (
<div>
<button className="btn btn-error btn-sm" onClick={handleChange}>
Delete
</button>
<input
type="checkbox"
checked={modal}
onChange={handleChange}
className="modal-toggle"
/>
<div className="modal">
<div className="modal-box">
<h3 className="font-bold text-lg">
Anda yakin untuk menghapus data ""?
</h3>
<div className="modal-action">
<button type="button" className="btn" onClick={handleChange}>
Close
</button>
<button type="button" onClick={handleDelete} className="btn">
Delete
</button>
</div>
</div>
</div>
</div>
);
}
api route
import { connectMongoDB } from "@/lib/mongodb";
import Appointment from "@/models/appointment";
import { NextResponse } from "next/server";
export async function DELETE(req) {
const id = req.nextUrl.searchParams.get("id");
await connectMongoDB();
await Appointment.findByIdAndDelete(id);
return NextResponse.json({ message: "Appointment deleted" }, { status: 200 });
}
Model
import mongoose, { Schema, models } from "mongoose";
const appointmentSchema = new Schema(
{
name: {
type: String,
required: true,
},
date: {
type: String,
required: true,
},
phone: {
type: String,
required: true,
},
terapist: {
type: String,
required: true,
},
statust: {
type: String,
required: true,
},
},
{ timestamps: true }
);
const Appointment =
models.Appointment || mongoose.model("Appointment", appointmentSchema);
export default Appointment;
CastError: Cast to ObjectId failed for value "undefined" (type string) at path "_id" for model "Appointment"
having hard time to figure how to passing id and difference between id and _id
2
Answers
It seems that the error is not within your db orm but at where you are passing the ID, can you check what is the value in
id
the error states that theid
that you are passing is undefined. Please check the value and ensure that it is being passed correctly.There’s no parameter sent with the
onClick
function. So, theid
parameter isundefined
. Therefore, it sends an API request with anundefined
id parameter like this:http://localhost:3000/api/appointment?id=undefined
On the client side, it is necessary to use an
ObjectID
to delete a document by using findByIdAndDelete() but the ID parameter comes from the request asundefined
, not anObjectID
. Therefore, it can’t find the related document from DB and returns this error.As a result, the issue is related to the client side. Need to send the correct ID to be deleted with the API parameter. Therefore, need to get the related row or only the
id
value as props in theDeleteAppointment
component.It would be better to send the whole row object into props if you will need to use other fields as well:
Otherwise, it’s enough to send only
id
:Then get the props as a parameter in the
DeleteAppointment
component:After that, because of reaching the related id into the props, you can use
props.id
orprops.row.id
in the request id instead of theid
parameter:If you send the whole row object as a prop, then you can use
props.row.id
:Hope, it’s clear and helpful