skip to Main Content

I’m making an e-commerce next.js app with Typescript and MongoDB.
This is my current file structure I will be referring to:

Folder Structure of my next.js app screenshot

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


  1. 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,

    ... all imports...
    
    export async function GET(req: NextApiRequest, res: NextApiResponse) {
      try {
        const id = req.query.id as string;
    
        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 });
      }
    }
    

    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.

    Login or Signup to reply.
  2. This solution involves changing NextApiRequest to NextRequest.

    In your api/singleProduct/route.tsx, you could use this line of code:

    import { NextRequest, NextResponse } from "next/server";
    
    export async function GET(req: NextRequest, res: NextResponse) {
        ...
        // This will get the "id" search parameter (/api/singleProduct?id=12345)
        const productId = req.nextUrl.searchParams.get("id");
        ...
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search