1

APP.JS import './App.css'; import {BrowserRouter as Router,Routes,Route,Navigate } from "react-router-dom"; import Home from "./pages/Home"; import Login from "./pages/Login"; import Register from "./pages/Register"; import BookingCar from "./pages/BookingCar"; import "antd/dist/antd.css"

function App() {
return (
 <Router>
   <Routes>
      <Route path='/' element={<Home/>}/> 
      <Route path="/login" element={<Login/>}></Route>
      <Route path="/register" element={<Register />}></Route>
      <Route path="/booking/:id" element={<BookingCar />}></Route>
   </Routes>
</Router>

); }

export default App;

BookingCar.js

import React, {useState,useEffect} from "react";
import { useDispatch, useSelector } from "react-redux";
import { getAllcars } from "../redux/action/carsAction";
import { useParams } from 'react-router-dom';
import Spinner from "../components/Spinner";
import DefaultLayout from "../components/DefaultLayout";
import  { Row, Col} from "antd";


export default function BookingCar({match}){

const { carid } = useParams();

const {cars} = useSelector(state => state.carsReducer)
const {loading} = useSelector(state => state.alertReducer)
const [car, setcar] = useState({})
const dispatch = useDispatch()


useEffect(() => {
    dispatch(getAllcars())
    if(cars.length>0){
        setcar(cars.find(o=>o._id === carid))
    }
}, [cars])

return(

    <DefaultLayout> 
         {loading  && (<Spinner/> )}
         <Row>
            <Col lg={10} sm={24} xs={24}>
                <img alt=""src={car.image} className="carimg"/>
                           
            </Col>
          
         </Row>
    </DefaultLayout> 
  
)

}

Home.js

import React, {useState,useEffect} from "react";
import { useDispatch, useSelector } from "react-redux";
import DefaultLayout from "../components/DefaultLayout";
import { getAllcars } from "../redux/action/carsAction";
import  { Button, Row, Col} from "antd";
import {Link} from "react-router-dom";
import Spinner from "../components/Spinner";
export default function Home(){

const {cars} = useSelector(state => state.carsReducer)
const {loading} = useSelector(state => state.alertReducer)
const dispatch = useDispatch()

useEffect(() => {
    dispatch(getAllcars())
}, [])

return(
   
    <DefaultLayout> 
         {loading === true && (<Spinner/> )}
        <Row justify="center" gutter={16} className="mt-5">
            {cars.map(car=>{
                return <Col lg={5} sm={24} xs={24}> 
                    <div className="car p-2 bs1 ">
                        <img alt=""src={car.image} className="carimg"/>
                        <div className="car-content d-flex align-items-center justify-content-between">
                            <div> 
                                <p>{car.name}</p> 
                                <p>{car.rentPerHour} Rent Per Hour</p> 
                            </div> 

                            <div> 
                                <button className="btn1 mt-2"><Link to={`/booking/${car._id}`}>Book now </Link></button> 
                              
                            </div>

                        </div> 
                    </div> 
                </Col> 
            })}
        </Row>
    </DefaultLayout> 
)

} In BookingCar.js i am trying to get the car details like id (image)but i am getting error So please help me how to solve this issue.

2 Answers 2

0

You're trying to access car before it's loaded/applied to state. Check if it exists first before trying to use it -

{car && (
  <Row>
    <Col lg={10} sm={24} xs={24}>
      <img alt=""src={car.image} className="carimg"/>
    </Col>
  </Row>
)}
Sign up to request clarification or add additional context in comments.

Comments

0

carid is undefined since it's not a defined route param (path="/booking/:id") so the .find function returns undefined.

You've valid car initial state

const [car, setcar] = useState({});

so you should be able to destructure (car.image & <img alt=""src={car.image} className="carimg"/>) from car without issue. The issue comes later when filtering cars by the cardid route param.

useEffect(() => {
  dispatch(getAllcars());
  if (cars.length > 0) {
    setcar(cars.find(o => o._id === carid));
  }
}, [cars]);

array.find can potentially return undefined if no match is found, so the UI should handle that. Route match params are also always strings, so if the _id fields are not also "string" type the strict equality won't work. Try doing a type-safe comparison by converting to strings.

cars.find(o => String(o._id) === carid)

...

return (
  <DefaultLayout> 
    {loading  && <Spinner />}
    {car && (
      <Row>
        <Col lg={10} sm={24} xs={24}>
          <img alt=""src={car.image} className="carimg" />
        </Col>
      </Row>
    )}
  </DefaultLayout>
);

Finally, you define the route match param as ":id" but destructure a carid in the component. Ensure the match params match.

If route is:

<Route path="/booking/:id" element={<BookingCar />} />

use const { id } = useParams();

otherwise, update the route param to match the code:

<Route path="/booking/:carid" element={<BookingCar />} />

use const { carid } = useParams();

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.