How can i post employee?
Maybe I'm doing something wrong? Is there another option? I don't know React at all. I just need a frontend for my application. This is the only problem on my way.
I do useState for Employee and useState for Department, but I don't understand how to nest Department in Employee for the future POST request.
export default function AddEmployee() {
// departments
const [departments, setDepartments] = useState([]);
useEffect(() => {
loadDepartments();
}, []);
const loadDepartments = async () => {
const result = await axios.get("http://localhost:8080/api/departments");
setDepartments(result.data);
};
const [dep, setDepartment] = useState({
id: "",
title: "",
description: ""
});
const onInputDepartmentChange = (event) => {
setDepartment({ ...dep, [event.target.name]: event.target.value });
};
// employees
const [employee, setEmployee] = useState({
name: "",
surname: "",
age: "",
phone: "",
experience: "",
department: {
id: "",
title: "",
description: ""
},
salary: ""
});
const { name, surname, age, phone, experience, department, salary } = employee;
const onInputChange = (event) => {
setEmployee({ ...employee, [event.target.name]: event.target.value });
};
// all
let navigate = useNavigate();
const onSubmit = async (event) => {
event.preventDefault();
await axios.post("http://localhost:8080/api/employees", employee);
navigate("/");
};
return (
<div className='container mb-5'>
<div className='row'>
<div className='col-md-6 offset-md-3 border shadow p-4 mt-4'>
<h2 className='text-center m-4 mb-5'>Add employee</h2>
<form onSubmit={(event) => onSubmit(event)}>
<div className="form-floating mb-3">
<input
type={"text"}
className="form-control"
id="name"
placeholder="Enter name of employee"
name='name'
value={name}
onChange={(event) => onInputChange(event)} />
<label htmlFor="name">Name</label>
</div>
<div className="form-floating mb-3">
<input
type={"text"}
className="form-control"
id="surname"
placeholder="Enter surname of employee"
name='surname'
value={surname}
onChange={(event) => onInputChange(event)} />
<label htmlFor="surname">Surname</label>
</div>
<div className="form-floating mb-3">
<input
type={"number"}
className="form-control"
id="age"
placeholder="Enter age of employee"
name='age'
value={age}
onChange={(event) => onInputChange(event)} />
<label htmlFor="age">Age</label>
</div>
<div className="form-floating mb-3">
<input
type={"text"}
className="form-control"
id="phone"
placeholder="Enter phone number of employee"
name='phone'
value={phone}
onChange={(event) => onInputChange(event)} />
<label htmlFor="phone">Phone number</label>
</div>
<div className="form-floating mb-3">
<input
type={"number"}
className="form-control"
id="experience"
placeholder="Enter experience of employee"
name='experience'
value={experience}
onChange={(event) => onInputChange(event)} />
<label htmlFor="experience">Experience</label>
</div>
<div className="mb-3">
<select
className="form-select"
aria-label="Department"
name="id"
onChange={(event) => onInputDepartmentChange(event)}>
<option defaultValue>Department</option>
{
departments.map((department, index) => (
<option key={index} value={department.id}>{department.title}</option>
))
}
</select>
</div>
<div className="form-floating mb-3">
<input
type={"text"}
className="form-control"
id="salary"
placeholder="Enter salary of employee"
name='salary'
value={salary}
onChange={(event) => onInputChange(event)} />
<label htmlFor="salary">Salary</label>
</div>
<button type='submit' className='btn btn-primary'>Submit</button>
<Link className='btn btn-outline-danger mx-2' to="/">Cancel</Link>
</form>
</div>
</div>
</div>
)
}
I see your issue you need to store all the data in one place so you can send it as one block in the POST
request.
First, we don't need this state:
const [dep, setDepartment] = useState({
id: "",
title: "",
description: ""
});
We can use just the employee state to do what we want.
const initialState={
name: "",
surname: "",
age: "",
phone: "",
experience: "",
salary: ""
department: {
id: "",
title: "",
description: ""
},
}
const baseUrl="http://localhost:8080/api"
export default function AddEmployee() {
const [employee, setEmployee] = useState(initialState);
const { name, surname, age, phone, experience, department, salary } = employee;
const onInputChange = (event) => {
setEmployee(prev=>({ ...prev, [event.target.name]:event.target.value}));
};
const onInputDepartmentChange = (event) => {
setEmployee(prev=>({ ...prev, department:{...prev.department,
[event.target.name]: event.target.value }}));
};
const loadDepartments = async () => {
const result = await axios.get(`${baseUrl}/departments`);
setDepartments(result.data);
};
const onSubmit = async (event) => {
event.preventDefault();
await axios.post(`${baseUrl}/employees`, employee);
navigate("/");
};
useEffect preferred to be at the end before the return and useState at first in this order component name => useState => contants => functions => api calles => useEffect => return.
useEffect(() => {
loadDepartments();
}, []);