Я создаю приложение в NextJS для практики, и мне трудно получить отдельные данные для удаления из базы данных с помощью функции findByIdAndDelete.
CastError: приведение к ObjectId не удалось для значения «не определено» (строка типа) по пути «_id» для модели «Встреча»
./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 handleChangeEvent() {
setModal(!modal);
}
return (
<div>
<button className = "btn btn-error btn-sm" onClick = {handleChangeEvent}>
Delete
</button>
<input
type = "checkbox"
checked = {modal}
onChange = {handleChangeEvent}
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 = {handleChangeEvent}>
Close
</button>
<button type = "button" onClick = {handleDelete} className = "btn">
Delete
</button>
</div>
</div>
</div>
</div>
);
}
Маршрут API:
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 });
}
Модель:
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: приведение к ObjectId не удалось для значения «не определено» (строка типа) по пути «_id» для модели «Встреча»
Трудно понять, как пройти id и разницу между id и _id.
вау, это работа, спасибо, это действительно помогло мне лучше понять, как передавать реквизиты дочернему компоненту



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Кажется, что ошибка произошла не в вашей базе данных, а в том месте, где вы передаете идентификатор. Можете ли вы проверить, какое значение в id ошибка указывает, что id, который вы передаете, не определен. Пожалуйста, проверьте значение и убедитесь, что оно передается правильно.
С помощью функции onClick параметр не передается. Итак, параметр id — это undefined. Поэтому он отправляет запрос API с параметром undefined id следующим образом: http://localhost:3000/api/appointment?id=undefined
На стороне клиента необходимо использовать ObjectID для удаления документа с помощью findByIdAndDelete(), но параметр ID поступает из запроса как undefined, а не как ObjectID. Поэтому он не может найти связанный документ в БД и возвращает эту ошибку.
В результате проблема связана с клиентской стороной. Необходимо отправить правильный идентификатор для удаления с помощью параметра API. Поэтому необходимо получить связанную строку или только значение id в качестве реквизита в компоненте DeleteAppointment.
Было бы лучше отправить весь объект строки в реквизит, если вам нужно будет использовать и другие поля:
// Send related row as prop
<DeleteAppointment row = {row} />
В противном случае достаточно отправить только id:
// Send only the related row's ID field as a prop
<DeleteAppointment id = {row.id} />
Затем получите реквизит в качестве параметра в компоненте DeleteAppointment:
export default function DeleteAppointment(props) {
...
}
После этого, из-за достижения связанного идентификатора в реквизите, вы можете использовать props.id или props.row.id в идентификаторе запроса вместо параметра id:
async function handleDelete() {
await fetch(`http://localhost:3000/api/appointment?id=${props.id}`, {
method: "DELETE",
});
router.refresh();
setModal(false);
}
Если вы отправите весь объект строки в качестве реквизита, вы можете использовать props.row.id:
async function handleDelete() {
await fetch(`http://localhost:3000/api/appointment?id=${props.row.id}`, {
method: "DELETE",
});
router.refresh();
setModal(false);
}
Надеюсь, понятно и полезно
С помощью функции
onClickвы не отправляли идентификатор функции удаления. Итак, идентификатор —undefined, аundefined— это неObjectId. Поэтому он не может найти соответствующие данные из базы данных. Вам нужно отправить соответствующую строку или только значение идентификатора в качестве реквизита:<DeleteAppointment row = {row} />или<DeleteAppointment id = {row.id} />затем получает реквизит в качестве параметра в компонентеDeleteAppointment. Затем используйтеprops.idилиprops.row.idв идентификаторе запроса вместо параметра id, например: await fetch(http://localhost:3000/api/appointment?id=${props.id}} или, если вы отправили строку, используйтеprops.row.id