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;
Advertisement
Answer
To access id in nextjs. I imported useRouter from next/router. Then I const router = useRouter(). Then const {id} = router.query