I'm trying to route a page to my project that will allow the user to edit an existing data entry within a MongoDB database, however I am getting this error. The intended function of the program is that a user will be able to select an edit button on a specific data entry, which will open a form allowing them to altar that entry's content. It should do this by making a get request using the data's ID, however there is something wrong happening when I try to concatenate the route string, and the data's ID. Here is my Main.js file, my VehiclesList.js file, and my EditVehicles.js file:
Main.js
import React, { Component } from "react";
import "./index.css";
import { Routes, Route } from "react-router-dom";
import VehicleList from "../VehicleList/index";
import AddVehicle from "../addVehicle/index";
import EditVehicle from "../editVehicle";
class Main extends Component {
render() {
return (
<div className="main">
<Routes>
<Route exact path="/" element={<VehicleList />} />
<Route path="/list" element={<VehicleList />} />
<Route path="/addVehicle" element={<AddVehicle />} />
<Route path="/editVehicle/:id" element={<EditVehicle />} />
</Routes>
</div>
);
}
}
export default Main;
VehiclesList.js
import React, { Component, useState } from "react";
import "./index.css";
import axios from "axios";
import { Link } from "react-router-dom";
import VehicleService from "../services/services";
class VehicleList extends Component {
constructor(props) {
super(props);
this.VehicleService = new VehicleService();
this.state = {
vehicles: [],
};
this.deleteVehicle = this.deleteVehicle.bind(this);
}
componentDidMount = () => {
this.getVehicleList();
};
//get all vehicles
getVehicleList() {
axios
.get("http://localhost:5000/vehicles")
.then((res) => {
console.log(res);
this.setState({
vehicles: res.data,
});
})
.catch((err) => {
console.log(err);
});
}
//delete vehicle
deleteVehicle(vehicleId) {
this.VehicleService.deleteVehicle(vehicleId);
this.getVehicleList();
window.location.reload(false);
}
render() {
const { vehicles } = this.state;
return (
<div className="vehicleList">
<table className="vehicleList_table">
<thead>
<tr className="vehicleList_table_head">
<th className="vehicleList_table_head_title">#</th>
<th className="vehicleList_table_head_title">Make</th>
<th className="vehicleList_table_head_title">Model</th>
<th className="vehicleList_table_head_title">Year</th>
<th className="vehicleList_table_head_title">Price</th>
<th className="vehicleList_table_head_title">Status</th>
<th className="vehicleList_table_head_title"></th>
<th className="vehicleList_table_head_title"></th>
</tr>
</thead>
<tbody className="vehicleList_table_body">
{vehicles &&
vehicles.map((vehicle, idx) => {
let status = "";
if (vehicle.isSold) {
status = "Sold";
} else {
status = "Available";
}
return (
<tr key={idx}>
<td className="vehicleList_table_item">{vehicle._id}</td>
<td className="vehicleList_table_item">{vehicle.make}</td>
<td className="vehicleList_table_item">{vehicle.model}</td>
<td className="vehicleList_table_item">{vehicle.year}</td>
<td className="vehicleList_table_item">{vehicle.price}</td>
<td className="vehicleList_table_item">{status}</td>
<td className="vehicleList_table_item">
<Link
to={"/editVehicle/" + vehicle._id}
style={{ fontSize: "1.5rem" }}
className="edit_btn"
>
edit
</Link>
</td>
<td className="vehicleList_table_item">
<button
onClick={() => this.deleteVehicle(vehicle._id)}
className="delete_btn"
>
Delete
</button>
</td>
</tr>
);
})}
</tbody>
</table>
</div>
);
}
}
export default VehicleList;
EditVehicles.js
import React, { Component } from "react";
import axios from "axios";
import { Link } from "react-router-dom";
class EditVehicle extends Component {
constructor(props) {
super(props);
this.state = {
make: "",
model: "",
year: "",
price: "",
isSold: "",
};
}
componentDidMount = () => {
this.getVehicleById();
};
//get vehicle by ID
getVehicleById() {
axios
.get(
"http://localhost:5000/vehicles/editVehicle/" +
this.props.match.params.id
)
.then((res) => {
this.setState({
make: res.data.make,
model: res.data.model,
year: res.data.year,
price: res.date.price,
isSold: res.data.isSold,
});
})
.catch((err) => {
console.log(err);
});
}
//handle changes to data
changeHandler = (e) => {
this.setState({ [e.target.name]: e.target.value });
};
//update record on submit
submitHandler = (e) => {
e.preventDefault();
const { make, model, year, price, isSold } = this.state;
axios
.post(
"http://localhost:5000/vehicles/editVehicle/" +
this.props.match.params.id,
{
make: make,
model: model,
year: year,
price: price,
isSold: isSold,
}
)
.then((res) => {
console.log(res);
this.props.history.push("/");
})
.catch((err) => {
console.log(err);
});
};
render() {
return (
<div className="editVehicle">
<form className="editVehicle_form" onSubmit={this.submitHandler}>
<Link to="/" className="back_btn">
Back
</Link>
<h1>Update Vehicle Details</h1>
<p>Please fill out all fields</p>
<input
name="make"
placeholder="Make"
type="text"
value={this.state.make}
onChange={this.changeHandler}
className="editVehicle_form_input"
/>
<br />
<input
name="model"
placeholder="Model"
type="text"
value={this.state.model}
onChange={this.changeHandler}
className="editVehicle_form_input"
/>
<br />
<input
name="year"
placeholder="Year"
type="text"
value={this.state.year}
onChange={this.changeHandler}
className="editVehicle_form_input"
/>
<br />
<input
name="price"
placeholder="Price"
type="text"
value={this.state.price}
onChange={this.changeHandler}
className="editVehicle_form_input"
/>
<br />
<label className="addVehicle_form_radio_label">
Available
<input
name="isSold"
type="radio"
value={false}
onChange={this.changeHandler}
className="editVehicle_form_radio"
/>
</label>
<label className="editVehicle_form_radio_label">
Sold
<input
name="isSold"
type="radio"
value={true}
onChange={this.changeHandler}
className="editVehicle_form_radio"
/>
</label>
<br />
<input type="submit" value="Save" className="editVehicle_submit" />
</form>
</div>
);
}
}
export default EditVehicle;
My Routes to the VehiclesList, AddVehicle and DeleteVehicle pages all work. the only issue I'm running into is routing the EditVehicle page.
at first I was getting the error "Cannot read properties of undefined('params'), and then I changed the route to the EditVehicles page to this:
<Route path="/editVehicle/:id" component={EditVehicle} />
when I did it this way, I got an error back saying that this route did not have an element, and would result in an empty page.
I also tried doing it this way:
<Route path='/editVehicle/:id render={(props) => <EditVehicle {...props} />} />
this too just gave me an error saying that the route did not have an element.
is there an issue in my code that I am not seeing? or is there an easier way to do this?