I’m making an e-commerce next.js app with Typescript and MongoDB.
This is my current file structure I will be referring to:
My mainPage.tsx file renders all of my products in cards. Using products.map and Link, I am linking each product to its product page like this:
{products.map((product: ProductModel) => (
<Link
key={product._id.toString()}
href={{
pathname: "/product",
query: {
id: `${product._id.toString()}`,
},
}}
>
<CategoryCard product={product} />
</Link>
))}
Here in my product/page.tsx file I get the id from searchParams and I know up to this point it works correctly, the "console.log("This is the id: ", searchParams.id);" line correctly shows the id. But it’s the fetching of the product here
const { product } = await getProduct(searchParams.id);
where it breaks and displays "Error fetching product details of product id {searchParams.id}" on the page. Here is the file:
const getProduct = async (id: string) => {
try {
const res = await fetch(
`http://localhost:3000/api/singleproduct?id=${id}`,
{
cache: "no-cache",
}
);
if (!res.ok) {
throw new Error(`Failed to fetch product with id ${id}`);
}
return res.json();
} catch (err) {
console.error("Error fetching product:", err);
throw err;
}
};
const ProductPage = async ({
searchParams,
}: {
searchParams: { id: string };
}) => {
console.log("This is the id: ", searchParams.id);
try {
const { product } = await getProduct(searchParams.id);
return <div>This is a {product.product_title}</div>;
} catch (error) {
console.error("Error fetching product:", error);
return (
<div>Error fetching product details of product id {searchParams.id}</div>
);
}
};
export default ProductPage;
Now this is the api/singleproduct/route.tsx file where the problem probably originates from. Here’s the code:
import Product from "../../models/Product";
import { NextResponse } from "next/server";
import { NextApiRequest, NextApiResponse } from "next";
export async function GET(req: NextApiRequest, res: NextApiResponse) {
console.log("Query parameters:", req.query);
const id = req.query.id as string;
console.log("this is the id:", id);
try {
if (!id) {
throw new Error("ID parameter is missing.");
}
console.log("This is the id:", id);
const product = await Product.findById(id);
if (!product) {
return NextResponse.json({ error: "Product not found" }, { status: 404 });
}
console.log("Product from MongoDB:", product);
return NextResponse.json({ product }, { status: 200 });
} catch (error) {
console.log("Something broke:", error);
return NextResponse.json({ message: "GET request failed.", error });
}
}
I get "Query parameters: undefined" in the console and the error "TypeError: Cannot read properties of undefined (reading ‘id’)". How can I fix this? Thanks a million.
2
Answers
The req.query object is undefined, which means the route isn’t receiving the query parameters properly. In your Next.js API route file api/singleproduct/route.tsx, you’re trying to access the query parameters using req.query.id. However, for query parameters passed in through a GET request, you should access them using req.query directly, without chaining it with id. Try something like this and see if this solves the issue,
Make sure that your API route is correctly configured and the request from your frontend correctly sends the id parameter. If you continue to face issues, double-check your frontend code where you’re making the request to ensure that the id parameter is being sent correctly.
This solution involves changing
NextApiRequest
toNextRequest
.In your
api/singleProduct/route.tsx
, you could use this line of code: