The above I hope help showing the Home.js pulling the User info working properly. When I click the Edit button for either User it takes me to the edit page where the URL shows properly pulling it for ID 5. The issue is that the page loads the form properly accept it has no user data prefilled based on the ID. I get the error below the URL about the ID being undefined. This is being pulled from an SQL database and the data is being pulled from a SPROC provided below which runs the Home Page fine but for some reason is not able to get the ID to do the edit page.
Any help please to get this resolved.
Home.js (this pulls the data fine with the same get sproc as the edit)
import axios from "axios";
import { Link } from "react-router-dom";
const Home = () => {
const [users, setUser] = useState([]);
useEffect(() => {
loadUsers();
}, []);
const loadUsers = async () => {
const result = await axios.get(`http://localhost:5000/getCollectors`);
setUser(result.data.reverse());
};
const deleteUser = async CollectorID => {
await axios.delete(`http://localhost:5000/deleteCollector/${CollectorID}`);
loadUsers();
};
return (
<div className="container">
<div className="py-4">
<h1>Home Page</h1>
<table className="table border shadow">
<thead className="thead-dark">
<tr>
<th scope="col">ID</th>
<th scope="col">Active</th>
<th scope="col">Name | Code</th>
<th scope="col">Aging Bucket</th>
<th scope="col">Program Bucket</th>
<th scope="col">Finance Company</th>
<th>Action</th>
</tr>
</thead>
<tbody>
{users.map((user) => (
<tr key={user.CollectorID}>
{/* <th scope="row">{index 1}</th> */}
<th scope="row">{user.CollectorID}</th>
<td></td>
<td>{user.FirstName} {user.LastName} | {user.CollectorCode}</td>
<td></td>
<td></td>
<td>{user.FinanceCompany}</td>
<td>
<Link className="btn btn-primary mr-2" to={`/users/${user.CollectorID}`}>
View
</Link>
<Link
className="btn btn-outline-primary mr-2"
to={`/users/edit/${user.CollectorID}`}
>
Edit
</Link>
<Link
className="btn btn-danger"
onClick={() => deleteUser(user.CollectorID)}
>
Delete
</Link>
</td>
</tr>
))}
</tbody>
</table>
</div>
</div>
);
};
export default Home;
EditUser.js (uses same sproc as the Home.js but trying to get by user ID which is where it breaks)
import axios from "axios";
import { useHistory, useParams } from "react-router-dom";
const EditUser = () => {
let history = useHistory();
const { CollectorID } = useParams();
const [user, setUser] = useState({
// CollectorID: '',
// ProgramBucketID: '',
// CollectorOptionsID: '',
// FinanceCompanyID: '',
Active: '',
LastName: '',
CollectorCode: '',
Aging1to15: '',
Aging31to45: '',
Aging31to60: '',
AgingOver60: '',
ProgramBucketA: '',
ProgramBucketB: '',
ProgramBucketC: '',
ProgramBucketSU: '',
FinanceCompany: ''
});
const { Active, LastName, CollectorCode, Aging1to15, Aging31to45, Aging31to60, AgingOver60, ProgramBucketA, ProgramBucketB, ProgramBucketC, ProgramBucketSU, FinanceCompany} = user;
const onInputChange = e => {
setUser({ ...user, [e.target.name]: e.target.value });
};
useEffect(() => {
loadUser();
}, []);
const onSubmit = async e => {
e.preventDefault();
await axios.put(`http://localhost:5000/UpdateUser/${CollectorID}`, user);
history.push("/");
};
const loadUser = async () => {
const result = await axios.get(`http://localhost:5000/getCollectors/${CollectorID}`);
setUser(result.data);
console.log(result.data);
};
return (
<div className="container">
<div className="w-75 mx-auto shadow p-5">
<h2 className="text-center mb-4">Edit A User</h2>
<form onSubmit={e => onSubmit(e)}>
<div className="form-group">
<input
type="text"
className="form-control form-control-lg"
placeholder="Active Status"
name="Active"
value={Active}
onChange={e => onInputChange(e)}
/>
</div>
<div className="form-group">
<input
type="text"
className="form-control form-control-lg"
placeholder="Enter Your Last Name"
name="LastName"
value={LastName}
onChange={e => onInputChange(e)}
/>
</div>
<div className="form-group">
<input
type="text"
className="form-control form-control-lg"
placeholder="Enter Your Collector Code"
name="CollectorCode"
value={CollectorCode}
onChange={e => onInputChange(e)}
/>
</div>
<div className="form-group">
<input
type="text"
className="form-control form-control-lg"
placeholder="Aging1to15"
name="Aging1to15"
value={Aging1to15}
onChange={e => onInputChange(e)}
/>
</div>
<div className="form-group">
<input
type="text"
className="form-control form-control-lg"
placeholder="Aging31to45"
name="Aging31to45"
value={Aging31to45}
onChange={e => onInputChange(e)}
/>
</div>
<div className="form-group">
<input
type="text"
className="form-control form-control-lg"
placeholder="Aging31to60"
name="Aging31to60"
value={Aging31to60}
onChange={e => onInputChange(e)}
/>
</div>
<div className="form-group">
<input
type="text"
className="form-control form-control-lg"
placeholder="AgingOver60"
name="AgingOver60"
value={AgingOver60}
onChange={e => onInputChange(e)}
/>
</div>
<div className="form-group">
<input
type="text"
className="form-control form-control-lg"
placeholder="ProgramBucketA"
name="ProgramBucketA"
value={ProgramBucketA}
onChange={e => onInputChange(e)}
/>
</div>
<div className="form-group">
<input
type="text"
className="form-control form-control-lg"
placeholder="ProgramBucketB"
name="ProgramBucketB"
value={ProgramBucketB}
onChange={e => onInputChange(e)}
/>
</div>
<div className="form-group">
<input
type="text"
className="form-control form-control-lg"
placeholder="ProgramBucketC"
name="ProgramBucketC"
value={ProgramBucketC}
onChange={e => onInputChange(e)}
/>
</div>
<div className="form-group">
<input
type="text"
className="form-control form-control-lg"
placeholder="ProgramBucketSU"
name="ProgramBucketSU"
value={ProgramBucketSU}
onChange={e => onInputChange(e)}
/>
</div>
<div className="form-group">
<input
type="text"
className="form-control form-control-lg"
placeholder="FinanceCompany"
name="FinanceCompany"
value={FinanceCompany}
onChange={e => onInputChange(e)}
/>
</div>
<button className="btn btn-warning btn-block">Update User</button>
</form>
</div>
</div>
);
};
export default EditUser;
Server.js
const cors = require('cors');
const bodyParser = require('body-parser');
const config = require('./src/dbfiles/dbConfig')
const app = express();
app.use(cors());
app.use(bodyParser.json({ extended: true }));
var sql = require("mssql");
// Get collectors
app.get('/getCollectors', (req, res) => {
sql.connect(config).then(pool => {
return pool.request()
.query(`Exec [CollectorAssignment].[sCollectorGet]`).then(result => {
res.send(result.recordset)
})
})
})
// Add Collector Personal Info
app.post('/addCollector', function (req, res) {
sql.connect(config).then(pool => {
return pool.request()
.query(`Exec CollectorAssignment.sCreateCollector
@Active='${req.body.Active}',
@FirstName='${req.body.FirstName}',
@MiddleInitial='${req.body.MiddleInitial}',
@LastName='${req.body.LastName}',
@CollectorCode='${req.body.CollectorCode}',
@CollectionTeamID='${req.body.CollectionTeamID}',
@Aging1to15='${req.body.Aging1to15}',
@Aging31to45='${req.body.Aging31to45}',
@Aging31to60='${req.body.Aging31to60}',
@AgingOver60='${req.body.AgingOver60}',
@ProgramBucketA='${req.body.ProgramBucketA}',
@ProgramBucketB='${req.body.ProgramBucketB}',
@ProgramBucketC='${req.body.ProgramBucketC}',
@ProgramBucketSU='${req.body.ProgramBucketSU}',
@FinanceCompany='${req.body.FinanceCompany}'
`)
.then(result => {
res.send(result)
})
})
});
//Update Collector
app.put('/UpdateUser/:CollectorID', function (req, res) {
sql.connect(config).then(pool => {
return pool.request()
.query(`Exec CollectorAssignment.sUpdateCollector
@CollectorID='${req.body.CollectorID}',
@CollectorOptionsID='${req.body.CollectorOptionsID}',
@ProgramBucketID='${req.body.ProgramBucketID}',
@FinanceCompanyID='${req.body.FinanceCompanyID}',
@Active='${req.body.Active}',
@LastName='${req.body.LastName}',
@CollectorCode='${req.body.CollectorCode}',
@Aging1to15='${req.body.Aging1to15}',
@Aging31to45='${req.body.Aging31to45}',
@Aging31to60='${req.body.Aging31to60}',
@AgingOver60='${req.body.AgingOver60}',
@ProgramBucketA='${req.body.ProgramBucketA}',
@ProgramBucketB='${req.body.ProgramBucketB}',
@ProgramBucketC='${req.body.ProgramBucketC}',
@ProgramBucketSU='${req.body.ProgramBucketSU}',
@FinanceCompany='${req.body.FinanceCompany}'
`)
.then(result => {
res.send(result.recordset)
})
})
});
// Delete Collector
app.delete('/deleteCollector/:CollectorID', (req, res) => {
sql.connect(config).then(pool => {
return pool.request()
.query(`DELETE FROM CollectorAssignment.tCollectorsTest
WHERE CollectorID = ${req.params.CollectorID}`).then(result => {
res.send(result.recordset)
})
})
})
app.listen(5000, () => {
console.log('running on port 5000');
})
Stored Procedure being ran for the getCollectors
GO
/****** Object: StoredProcedure [CollectorAssignment].[sCollectorGet] Script Date: 3/29/2022 2:37:07 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: Wesley Seitz
-- Create date: 01/13/2022
-- Description: To pull in collector information for the options page of the assignmnet tool
-- =============================================
ALTER PROCEDURE [CollectorAssignment].[sCollectorGet]
-- Add the parameters for the stored procedure here
--@CollectorID INT
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
-- Insert statements for procedure here
SELECT
Active,
FirstName,
LastName,
CollectorCode,
Aging1to15,
Aging31to45,
Aging31to60,
AgingOver60,
ProgramBucketA,
ProgramBucketB,
ProgramBucketC,
ProgramBucketSU,
FinanceCompany,
tCollectorsTest.CollectorID,
tCollectorOptionsTest.ProgramBucketID,
tCollectorOptionsTest.FinanceCompanyID,
tCollectorOptionsTest.CollectorOptionsID
FROM CollectorAssignment.tCollectorsTest
INNER JOIN CollectorAssignment.tCollectorOptionsTest ON tCollectorOptionsTest.CollectorID = tCollectorsTest.CollectorID
INNER JOIN CollectorAssignment.tProgramBucketTest ON tProgramBucketTest.ProgramBucketID = tCollectorOptionsTest.ProgramBucketID
INNER JOIN CollectorAssignment.tFinanceCompanyTest ON tFinanceCompanyTest.FinanceCompanyID = tCollectorOptionsTest.FinanceCompanyID
END
CodePudding user response:
As discussed in the comments, your issue here was that, in your EditUser
component, you were trying to access a property called CollectorID
from the result of useParams()
but the only property in this object was id
. Changing the line
const { CollectionID } = useParams();
to
const { id } = useParams();
and then changing subsequent references from CollectorID
to id
resolves the 404 by populating the correct id in the url.
Your follow-up question of why you are not seeing your data populate in the EditUser
component should probably be asked in another question (I'd advise trying to recreate the issue with a simpler code example).