Reputation: 55
Here is my code. I am getting student's data from backed, filtering it.
I am not able to set the default value for the select option and neither is setAssignedStudent
working, in the console, I am getting undefined
. Please let me know how to fix this.
//here is sample of students array
// let students- [ {name: "abc", email:"abc.com", mentor:"" },
// {name: "abc", email:"abc.com", mentor:"cda" }, {name: "abc", email:"abc.com", //mentor:"" }]
useEffect(() => {
const getStudents = async () => {
try {
const res = await fetch("http://localhost:3001/students");
const data = await res.json();
//console.log(data);
//filtering students based on who doesn;t have mentor
let filter = data.filter((e) => {
return e.mentor === "";
});
if (filter.length > 0) setStudents(filter);
} catch (err) {
console.log(err);
}
};
getStudents();
}, []);
const [assignedStudent, setAssignedStudent] = useState(students[1]);
const handleChange = (e) => {
setAssignedStudent(
students.find((student) => student._id == e.target.value)
);
console.log(assignedStudent);
};
const handleSubmit = async (e) => {
e.preventDefault();
console.log(assignedStudent);
}
<form onSubmit={(e) => handleSubmit(e)}>
<select onChange={handleChange} value={assignedStudent}>
{students.map((student) => {
return (
<>
<option key={student._id} value={student.id}>
{student.name}
</option>
</>
);
})}
</select>
<button type="submit">Submit </button>
</form>
Upvotes: 4
Views: 1799
Reputation: 8915
your students object is empty before the API call and was not initialized in your setState
. so using students.map
in your select
element will cause the error (since you can't map through an undefined array).
There are two important things before using the map
with arrayes:
check its declaration/definition by a simple if
statement:
{
if(myArrayOfData) {
myArrayOfData.map(
// rest of the codes ...
)
}
}
Or with using ?
shorthanded of if
{
myArrayOfData?.map(
// rest of the codes ...
)
}
check for the contents of the array and use the map
function after checking its length (which tells you the data has arrived from the API call etc. and is ready to process)
{
if(myArrayOfData) {
if(myArrayOfData.length > 0) {
myArrayOfData.map(
// rest of the codes ...
)
}
}
}
while the above snippet works properly, you can simplify it by checking both if
conditions together:
{
if(myArrayOfData?.length > 0) {
myArrayOfData.map(
// rest of the codes ...
)
}
}
In real-world examples, you may need to show some loading components while the data is fetching.
{
if(myArrayOfData?.length > 0) {
myArrayOfData.map(
// rest of the codes ...
)
} else {
<Loading />
}
}
const anEmptyArray = []
if(anEmptyArray){
// rest of the codes ...
}
The result of comparison on if(anEmptyArray)
is always true
with an empty array.
Upvotes: 3
Reputation: 4723
The option value should be _id. In your find you are comparing with student._id
but in the option the value props you passed is student.id
that's why find returns undefined
<option key={student._id} value={student._id}
{student.name}
</option>
Upvotes: 2