next.jsfetch

route handler only recieve POST requests


I have table component that provides functionality to add, edit and delete materials, but only add material works, deleting or editing material doesn't work, the method in the route handler doesn't seem to get reached as i try console log anything but it doesn't work, when i click delete it does send request to http://localhost:3000/ar/admin/materials/api/12 with status code of 200 and it returns an html response, console.log(data) in handleDelete function returns error yntaxError: Unexpected token '<', "<!DOCTYPE "... is not valid JSON Table.jsx


// works
  const handleAdd = async () => {
    if (newMaterialName && newPrice && !isNaN(newPrice)) {
      const newItem = {
        material_name: newMaterialName,
        material_price: parseFloat(Number(newPrice).toFixed(2)),
      };

      try {
        const response = await fetch(
          `http://localhost:3000/${locale}/admin/materials/api`,
          {
            method: "POST",
            headers: {
              "Content-Type": "application/json",
            },
            body: JSON.stringify(newItem),
          }
        );

        if (response.ok) {
          const data = await response.json();
          // Add the new material to the local state
          setMaterials([...materials, { id: data.id, ...newItem }]);
          setNewMaterialName("");
          setNewPrice("");
        } else {
          console.error("Failed to add material");
        }
      } catch (error) {
        console.error("Error adding material:", error);
      }
    }
  };

// doesn't work
  const handleDelete = async (id) => {
    try {
      const response = await fetch(
        `http://localhost:3000/${locale}/admin/materials/api/${id}`,
        {
          method: "DELETE",
          headers: {
            "Content-Type": "application/json",
          },
        }
      );

      if (!response.ok) return;

      // Remove the material from the local state
      setMaterials(materials.filter((material) => material.id !== id));

      const data = await response.json();
      console.log(data);
    } catch (error) {
      console.error("Error deleting material:", error);
    }
  };

app/[locale]/(protected)/admin/materials/api/route.jsx

export async function DELETE(request, { params }) {
  const t = await getTranslations("HomePage");
  const { id } = await params;
  console.log(id);

  if (!id) {
    return Response.json(
      { message: "Material ID is required" },
      { status: 400 }
    );
  }

  try {
    await db("DELETE FROM materials WHERE id = ?", [id]);
    console.log("well done");
    return Response.json(
      { message: "Material deleted successfully" },
      { status: 200 }
    );
  } catch (error) {
    console.log(error);
    return Response.json({ message: t("somethingWrong") }, { status: 500 });
  }
}


Solution

  • I think the issue is you are handling both POST and DELETE handlers in the same file. Dynamic parameters like ID, you need to separate the folder structure. Keep you current route file for the POST request. You need a new file for the DELETE request:

    app/[locale]/(protected)/admin/materials/api/[id]/route.js

    and I just noticed your api route file has jsx extension. But you should use js instead.

    So your DELETE route file would be:

    export async function DELETE(request, { params }) {
      const { id } = params; // No need to await here. because it is an object.
      console.log(id);
    
      if (!id) {
        return Response.json(
          { message: "Material ID is required" },
          { status: 400 }
        );
      }
    
      try {
        await db("DELETE FROM materials WHERE id = ?", [id]);
        console.log("well done");
        return Response.json(
          { message: "Material deleted successfully" },
          { status: 200 }
        );
      } catch (error) {
        console.log(error);
        return Response.json({ message: t("somethingWrong") }, { status: 500 });
      }
    }