1

I can't delete a specific document by its id in MongoDB. In Next.js, I have this handler to delete a specific chat by id. I was able to delete all documents using deleteMany method, but can not delete a specific document by id.

export default async function handler(req: any, res: any) {
  try {
    const client = await clientPromise;
    const db = client.db("mydb");
    const { chatId } = req.body;

    await db.collection("chats").deleteOne({
      _id: new ObjectId(chatId),
    });

    res.status(200).json({});

  } catch (error) {
    ...
  }
}

On pressing a delete button I'm calling a function below:

 const handleDeleteSingleChat = async () => {
    await fetch(`/api/database/deleteChat`, {
      method: "DELETE",
      body: JSON.stringify({
        chatId: chatId,
      }),
    });
  };

My document in MongoDB looks like:

{
  _id: ObjectId(64747668f6eefac44a882b35);
  ...
}

So far I've tried using different REST API methods. I've also tested chatId value and it works fine. I'm not exactly sure what to return in a handler so I just returned an empty object.

Note: I do not get any errors and network shows that fetch function was successful.

Update: I'm able to .deleteOne by writing document's string id directly, the problem is in chatId value, but can't figure what.

export default async function handler(req: any, res: any) {
  ...

    await db.collection("chats").deleteOne({
      _id: new ObjectId("64747668f6eefac44a882b35"),
    });
  ...
}
Roma Kim
  • 321
  • 1
  • 8
  • 1
    "_I've also tested chatId value and it works fine_": do you refer to `chatId` in `const { chatId } = req.body`? I suspect `fetch` misses `headers: {'Content-Type': 'application/json'}`, in which case your backend would have `chatId` as `undefined` – ghybs May 29 '23 at 10:47
  • I've figured it out. I've included ```headers: { "content-type": "application/json"}``` and changed method to ```POST```. I do not know why ```POST``` method worked here, but ```DELETE``` didn't. If somebody can explain it, it would be really nice. Is it because I didn't specifically filtered ```if request.method == 'post'```. I would love some clarification. – Roma Kim May 29 '23 at 10:52

1 Answers1

1

Your fetch call is very probably missing a content type, so that your body is converted to JSON in the backend:

fetch(`/api/database/deleteChat`, {
  method: "POST",
  headers: {
    // Ensure body will be interpreted as JSON by backend
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    chatId: chatId,
  }),
});

Furthermore, in the case of DELETE method, the id should typically be passed in the URL, rather than in the request body. See Is an entity body allowed for an HTTP DELETE request?

Looks like Next.js started to ignore the request body in the case of a DELETE method only recently, leading to confusion among developers relying on the old behaviour: see vercel/next.js#49353

ghybs
  • 47,565
  • 6
  • 74
  • 99