javascriptnode.jsreactjsexpressnext.js

Next.js keeps throwing error params is undefined


I have successfully connected my custom server using Node.js and Express.js with Next.js. I'm trying to fetch a car by its id whenever I click it among other cars, so I can have that particular car only. But I keep getting an error saying params is undefined even though I get the id at the back of my link whenever I click on the single car in the browser. I've tried fetching the data using thunder client and everything works fine. I believe something is wrong with my frontend logic.

This is where I'm trying to fetch the data with the id

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>


import Layout from "@/components/Layout";
import Image from "next/image";
import Link from "next/link";
import { useEffect, useState } from "react";
import Authorization from "@/HOC/Authorization";
import axios from "axios";

const Car = () => {
  const [data, setData] = useState("");

  const oneCar = async (params) => {
    const { id } = params;

    const res = await axios.get(`http://localhost:5000/one-car/${id}`);

    setData(res.data);
    if (res.status !== 200) {
      console.log(res.status);
    }
  };

  useEffect(() => {
    oneCar();
  }, []);

  return (
    <Layout>
      {data && (
        <div className="flex flex-col w-11/12 mx-auto mt-8 justify-center bg-blue-200 rounded-lg shadow">
          <div className="flex w-full justify-center mt-6 px-4 mx-auto box-shadow-lg  h-2/4 relative">
            <Image
              src="/assets/images/d17.jpg"
              alt="shopping image"
              className="mx-auto flex rounded-lg inset-0 w-full h-2/4 object-cover"
              width={1000}
              height={500}
            />
          </div>
          <form className="flex-auto p-6">
            <div className="flex flex-wrap">
              <h1 className="flex-auto text-xl font-semibold text-gray-800">
                {data.carName}
              </h1>
              <div className="text-xl font-semibold text-gray-700 ">
                {data.carPrice}
              </div>
              <div className="w-full flex-none text-sm font-medium text-gray-500  mt-2">
                In stock
              </div>
            </div>
            <div className="flex items-baseline mt-4 mb-6 text-gray-800 ">
              <Link
                href="#"
                className="ml-auto hidden md:block text-sm text-gray-500  underline"
              >
                Size Guide
              </Link>
            </div>
            <div className="flex mb-4 text-sm font-medium">
              <button
                type="button"
                className="py-2 px-4  bg-blue-700 hover:bg-blue-800 focus:ring-indigo-500 focus:ring-offset-indigo-200 text-white w-full sm:w-1/4 transition ease-in duration-200 text-center text-base font-semibold shadow-md focus:outline-none focus:ring-2 focus:ring-offset-2 mx-auto rounded-lg "
              >
                Buy now
              </button>
            </div>
            <p className="text-sm text-gray-500 text-center ">
              Free shipping on all continental US orders.
            </p>
          </form>
        </div>
      )}
    </Layout>
  );
};

export default Authorization(Car);

This is where I fetch all cars and makes the id a parameter to the link address

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

import Image from "next/image";
import Layout from "@/components/Layout";
import Pagination from "@/components/Pagination";
import { GiBinoculars } from "react-icons/gi";
import { useGetAllCarsQuery } from "@/store/ReduxStore/getAllCarsApi";
import Link from "next/link";

const Market = () => {
//I use RTK Query to fetch the data, and It was successfully fetched
  const { data, isLoading, error } = useGetAllCarsQuery();


  return (
    <Layout>
      <div className="2xl:container 2xl:mx-auto">
        <div className=" py-3 lg:px-20 md:px-6 px-4">
          <div className=" flex justify-center mt-3 items-center">
            <div className=" flex space-x-3 justify-center items-center">
              <span className="bg-blue-800 px-4 py-2 rounded-md text-2xl text-white">
                <GiBinoculars />
              </span>
              <input
                type="search"
                className="border-b-2 w-9/12 border-gray-700 -mb-3 leading-5 text-lg p-2 focus:outline-none"
                placeholder="Search for cars here..."
              />
            </div>
          </div>
          <hr className=" w-full bg-gray-200 my-6" />

          <div className=" grid lg:grid-cols-4 sm:grid-cols-2 grid-cols-1 lg:gap-y-12 lg:gap-x-8 sm:gap-y-10 sm:gap-x-6 gap-y-6 lg:mt-12 mt-10">
            {data?.map((cars, i) => (
              <Link
                key={i}
                href="/[id]"
                as={`${cars._id}`}
//I insert the id here
                className="relative"
                passHref
              >
                <div>
                  <div className=" relative group">
                    <div className="caroverlay"></div>
                    <Image
                      width={600}
                      height={400}
                      className="rounded-md w-full"
                      src="/assets/images/d17.jpg"
                      alt="A girl Posing Img"
                    />
                    <div className=" absolute bottom-0 p-8 w-full opacity-0 group-hover:opacity-100 z-20">
                      <button className="text-base font-bold leading-4 text-gray-600 hover:bg-gray-300 hover:text-gray-700 bg-white py-3 w-full">
                        Add to your garage
                      </button>
                      <button className=" bg-transparent  text-base font-bold leading-4 border-2 hover:bg-gray-300 hover:text-gray-700 border-white py-3 w-full mt-2 text-white">
                        View Car
                      </button>
                    </div>
                  </div>

                  <p className="  text-xl leading-5 text-gray-600 md:mt-6 mt-4">
                    {cars.carName}
                  </p>
                  <p className=" font-semibold text-xl leading-5 text-gray-800 mt-4">
                    <span>$</span> {cars.carPrice}
                  </p>
                </div>
              </Link>
            ))}
          </div>

          {/* _______________________________________________________ */}

          <Pagination />

          {/* _______________________________________________________ */}
        </div>
      </div>
    </Layout>
  );
};

export default Market;

Here is my backend logic

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

const router = require("express").Router();
const auth = require("../../middleware/auth");
const Car = require("../../Model/CarSchema");

router.get("/onecar/:id", auth, async (req, res) => {
  try {
    const car = await Car.findById(req.params.id);
    res.status(200).json(car);
  } catch (err) {
    res.status(500).json({ msg: "Server Error" });
  }
});

module.exports = router;


Solution

  • To access id in nextjs. I imported useRouter from next/router. Then I const router = useRouter(). Then const {id} = router.query