I have a dropdown of data from API. I want to be able to render the name of the HMO list but append the name and id of the SELECTED item.
const Form = () => {
const [hmo, setHmo] = useState([]);
const [selectedHmo, setSelectedHmo] = useState("");
const [file, setFile] = useState(null);
const getHmo = useCallback(async () => {
try {
const fetchHmo = await Axios.post("https://pshs3.herokuapp.com/hmo");
const resultHmo = fetchHmo.data.data;
setHmo(resultHmo);
} catch (err) {
console.log(err);
}
}, []);
useEffect(() => {
getHmo();
}, [getHmo]);
const submitForm = (e) => {
e.preventDefault();
var enrollData = new FormData();
enrollData.append("file", file);
enrollData.append("hmo_id", selectedHmo);
enrollData.append("hmo_name", ?? )
Axios({
method: "POST",
url: "https://jsonplaceholder.typicode.com/posts",
headers: {
"Content-Type": "multipart/form-data",
},
data: enrollData,
})
.then((response) => {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
};
return (
<div className="form-container">
<Container>
<form onSubmit={submitForm}>
<div className="textfield">
<TextField
className="box"
select
name="hmo"
required
SelectProps={{
native: true,
}}
sx={{
width: "23ch",
}}
value={selectedHmo}
onChange={(e) => setSelectedHmo(e.target.value)}
>
<option>Select HMO</option>
{hmo?.map((res) => (
<option value={res.id} key={res.id}>
{res.name}
</option>
))}
</TextField>
<TextField
className="box"
required
name="file"
accept=".xlsx, .xls, .csv"
type="file"
label="Upload File (.csv, xls, xlsx)"
onChange={(e) => setFile(e.target.files[0])}
sx={{
width: "24ch",
}}
/>
</div>
<div className="btn">
<Button
type="submit"
variant="contained"
color="success"
>
Upload
</Button>
</div>
</div>
</form>
</Container>
</div>
);
};
export default Form;
I got confused at the point of appending the formdata fields as I can access the item id by value={res.id} from hmo map but I need to access the name and id. Then, append to form data before submission.
CodePudding user response:
You need to find the name from id, try something like below.
var enrollData = new FormData();
const hmoDetails = hmo.find(hmoItem => hmoItem.id === selectedHmo);
enrollData.append("file", file);
enrollData.append("hmo_id", selectedHmo);
enrollData.append("hmo_name", hmoDetails && hmoDetails.name )
CodePudding user response:
So the onChange property takes in any function. Right now it looks like this:
(e) => setSelectedHmo(e.target.value)
this can be written into something more dynamic for your use case.
(e) => {
const value = e.target.value
const name = e.target.name
const id = e.target.id
setSelectedHmo({value: value, name: name; id: id}) }
This way, selectedHmo stores value, name, and id. You can change this according to your use case and how you want to store things. Note this does change selectedHmo into an object, and is no longer a string.
If functions get long, you can even have the function declared prior to the return/render method in react, and pass that function name into the onChange handler.
Ex:
const Form = () =>{
[selectedHmo, setSelectedHmo] = useState({})
const selectedHmoChange = (e) ->{
const value = e.target.value
const name = e.target.name
const id = e.target.id
setSelectedHmo({value: value, name: name; id: id})
}
return (
<form onSubmit={submitForm}>
<div className="textfield">
<TextField
className="box"
select
name="hmo"
required
SelectProps={{
native: true,
}}
sx={{
width: "23ch",
}}
value={selectedHmo.value}
onChange = {selectHmoChange}
</TextField>
</form>
)
}
Now that you have all the data you need in selectedHmo, we can change the onSubmit function, since remember selectedHmo now looks like this: {id: id, name: name, value: value}
const submitForm = (e) => {
e.preventDefault();
var enrollData = new FormData();
enrollData.append("file", file);
enrollData.append("hmo_id", selectedHmo.id);
enrollData.append("hmo_name", selectedHmo.name )
}