AddEmployee
component that includes a dropdown list for selecting the department instead of manually entering the deptId
. This modification ensures a better user experience by allowing users to select a department from a preloaded list.Key Changes:
- Fetch Departments: The component fetches the department list from an API (
http://localhost:9090/api/departments
). - Dropdown for Department Selection: Instead of entering a department ID manually, users can select from a dropdown.
- Improved Error Handling: Added better error handling and logging.
import axios from "axios";
import { Form, Button, Container, Alert } from "react-bootstrap";
import { useNavigate } from "react-router-dom";
const AddEmployee = () => {
const [employee, setEmployee] = useState({
empName: "",
designation: "",
dateOfJoining: "",
salary: 0,
empPhoneNumber: "",
isActive: true,
deptId: "",
});
const [departments, setDepartments] = useState([]);
const [error, setError] = useState("");
const navigate = useNavigate();
const EMPLOYEE_API_URL = "http://localhost:9090/api/employees";
const DEPARTMENT_API_URL = "http://localhost:9090/api/departments";
// Fetch department list from API
useEffect(() => {
const fetchDepartments = async () => {
try {
const response = await axios.get(DEPARTMENT_API_URL);
setDepartments(response.data);
} catch (error) {
console.error("Error fetching departments:", error);
setError("Failed to load departments.");
}
};
fetchDepartments();
}, []);
const handleSubmit = async (e) => {
e.preventDefault();
try {
const response = await axios.post(EMPLOYEE_API_URL, employee);
if (response.status === 200 || response.status === 201) {
navigate("/"); // Redirect to the employee list after successful addition
}
} catch (error) {
setError("Error adding employee. Please try again.");
console.error("Error adding employee:", error);
}
};
const handleChange = (e) => {
const { name, value } = e.target;
setEmployee((prevEmployee) => ({
...prevEmployee,
[name]: value,
}));
};
return (
<Container>
<h1 className="mb-4">Add Employee</h1>
{error && <Alert variant="danger">{error}</Alert>}
<Form onSubmit={handleSubmit}>
<Form.Group className="mb-3">
<Form.Label>Name</Form.Label>
<Form.Control
type="text"
name="empName"
value={employee.empName}
onChange={handleChange}
required
/>
</Form.Group>
<Form.Group className="mb-3">
<Form.Label>Designation</Form.Label>
<Form.Control
type="text"
name="designation"
value={employee.designation}
onChange={handleChange}
required
/>
</Form.Group>
<Form.Group className="mb-3">
<Form.Label>Date of Joining</Form.Label>
<Form.Control
type="date"
name="dateOfJoining"
value={employee.dateOfJoining}
onChange={handleChange}
required
/>
</Form.Group>
<Form.Group className="mb-3">
<Form.Label>Salary</Form.Label>
<Form.Control
type="number"
name="salary"
value={employee.salary}
onChange={handleChange}
required
/>
</Form.Group>
<Form.Group className="mb-3">
<Form.Label>Phone Number</Form.Label>
<Form.Control
type="text"
name="empPhoneNumber"
value={employee.empPhoneNumber}
onChange={handleChange}
required
/>
</Form.Group>
{/* Department Dropdown */}
<Form.Group className="mb-3">
<Form.Label>Department</Form.Label>
<Form.Select
name="deptId"
value={employee.deptId}
onChange={handleChange}
required
>
<option value="">Select Department</option>
{departments.map((dept) => (
<option key={dept.deptId} value={dept.deptId}>
{dept.deptName}
</option>
))}
</Form.Select>
</Form.Group>
<Form.Group className="mb-3">
<Form.Check
type="checkbox"
name="isActive"
label="Is Active"
checked={employee.isActive}
onChange={(e) =>
setEmployee({ ...employee, isActive: e.target.checked })
}
/>
</Form.Group>
<Button variant="primary" type="submit">
Add Employee
</Button>
</Form>
</Container>
);
};
export default AddEmployee;
Explanation of the handleChange
Function
This function is used to update the state of the employee
object dynamically whenever an input field changes. It ensures that all form fields update their respective values without overwriting the existing state.
Breakdown of the Code:
Step-by-Step Explanation:
Extract the
name
andvalue
from the input field (e.target
)e.target
refers to the input field that triggered theonChange
event.name
corresponds to thename
attribute of the input field (e.g.,"empName"
,"designation"
, etc.).value
is the current value entered in the input field.
Update the
employee
state usingsetEmployee
- The function takes the previous state (
prevEmployee
) and creates a new state object. - The spread operator (
...prevEmployee
) ensures that all existing properties of theemployee
object remain unchanged. [name]: value
dynamically updates the specific field that changed, using thename
extracted frome.target
.
- The function takes the previous state (
Example of How It Works
Initial State (employee
object):
Scenario: User Types "John Doe" in the Name Field
- The
name
of this field is"empName"
, and when the user types"John Doe"
, thevalue
is"John Doe"
. - The function updates the state:
- Now, the updated state:
Scenario: User Selects a Department from the Dropdown
- Suppose the user selects the IT department, which has a
deptId
of"2"
. - The function updates the state:
- Updated state:
Key Benefits of This Approach
✅ Dynamic Field Updates: Works for all input fields (text, date, number, dropdowns) without writing separate handlers.
✅ Prevents Overwriting: The spread operator (...prevEmployee
) ensures only the modified field updates while keeping the other fields intact.
✅ Reusability: The function is generic and can be used for any form input field with a name
attribute.
This pattern is a best practice in React for handling form state efficiently!
No comments:
Post a Comment