In my application, I am trying to edit a task, which requires the task id to be done, but for some reason my id does not get extracted using useParams. Below is my EditTask.jsx code, the address bar just shows http://localhost:5173/todos/edit/:id
import React, { useState, useEffect } from "react";
import BackButton from "../components/BackButton.jsx";
import Spinner from "../components/Spinner.jsx";
import axios from "axios";
import { useNavigate, useParams} from "react-router-dom";
const EditTask = () => {
const [task, setTask] = useState("");
const [loading, setLoading] = useState(false);
const navigate = useNavigate();
const {id} = useParams();
console.log(id);
useEffect(() => {
setLoading(true);
axios
.get(`http://localhost:5000/api/todos/${id}`)
.then((res) => {
setTask(res.data.task);
setLoading(false);
})
.catch((error) => {
setLoading(false);
console.log(error);
});
}, []);
const handleEditTask = () => {
const data = {
task,
};
setLoading(true);
axios
.put(`http://localhost:5000/api/todos/${id}`, data)
.then(() => {
setLoading(false);
navigate("/");
})
.catch((error) => {
setLoading(false);
console.log(error);
});
};
return (
<div className="p-4">
<BackButton />
<h1 className="text-3xl my-4">{id}</h1>
{loading ? <Spinner /> : ""}
<div className="flex flex-col border-2 border-solid border-sky-400 rounded-xl w-[600px] p-4 mx-auto">
<div className="my-4">
<label className="text-xl mr-4 text-gray-500">Task</label>
<input
type="text"
value={task}
onChange={(e) => setTask(e.target.value)}
className="border-2 border-solid border-gray-500 px-4 py-2 w-full"
/>
</div>
<button className="p-2 bg-sky-400" onClick={handleEditTask}>
Edit
</button>
</div>
</div>
);
};
export default EditTask;
This is App.jsx with Routes
import React from 'react'
import { Routes, Route } from "react-router-dom";
import Home from "./pages/Home.jsx";
import CreateTask from "./pages/CreateTask.jsx";
import DeleteTask from "./pages/DeleteTask.jsx";
import EditTask from "./pages/EditTask.jsx";
import ShowTask from "./pages/ShowTask.jsx";
const App = () => {
return (
<Routes>
<Route path="/" element={<Home/>}/>
<Route path="/todos/create" element={<CreateTask/>}/>
<Route path="/todos/details/:id" element={<ShowTask/>}/>
<Route path="/todos/edit/:id" element={<EditTask/>}/>
<Route path="/todos/delete/:id" element={<DeleteTask/>}/>
</Routes>
)
}
export default App
This is server side routes.js
router.put("/todos/:id", async (req, res) => {
try {
if (!req.body.task) {
res.status(400).json({ msg: "empty task field" });
}
const { id } = req.params;
const result = await taskModel.findByIdAndUpdate(id, req.body);
if (!result) {
return res.status(400).json({ msg: "task not found" });
}
return res.status(200).json({ msg: "task successfully updated" });
} catch (error) {
console.log(error);
}
});
The edit request works fine using Postman and also works fine when I hardcode an “id” value instead of rendering it dynamically,when i console log id, it just shows (:id). the app should populate the edit task field and when clicked on edit, edit and update the task and return back to Home.jsx
enter image description here
Kevin Anthony is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.