Reputation: 91
Im trying to make dependent dropdown list. In the first one menu i choose car brand. In 2nd menu I should see only models of selected brand. In a function selectBrand I am trying to set new value of selectedBrand and set models of selected brand to models arrays but in 2nd setAdData I get Uncaught TypeError: Cannot read properties of undefined (reading 'models'). How Can I fix that?
const [adData, setAdData] = useState({
selectedBrand: "",
models: [],
selectedModel: "",
productionYear: "",
countryOfOrigin: "",
typeOfFuel: "",
bodyType: "",
amountOfDoors: "",
typeOfGearbox: "",
typeOfDrive: "",
color: "",
typeOfColor: "",
description: "",
vin: "",
engineCapacity: "",
mileage: "",
horsePower: "",
price: "",
creator: "",
image: "",
});
const selectBrand = (e) => {
setAdData({...adData, selectedBrand: e.target.value});
setAdData({...adData, models: data.cars.find(car => car.brand===e.target.value).models})
}
return (
<Paper className={classes.paper}>
<form autoComplete="off" noValidate className={`${classes.root} ${classes.form}`} onSubmit={handleSubmit}>
<Typography variant="h6">Brand</Typography>
<Select fullWidth value={adData.selectedBrand} onChange={selectBrand.bind(this)
}>
{data.cars.map((car, key) => {
return <MenuItem key={key} value= {car}>{car.brand}</MenuItem>
})}
</Select>
<Typography variant="h6">Model</Typography>
<Select fullWidth value={adData.selectedModel} onChange={(e) =>
setAdData({...adData, selectedModel: e.target.value})
}>
{
adData.models.map((model, key) => {
return <MenuItem key={key} value={model}>{model}</MenuItem>
})
}
</Select>
<Button className={classes.buttonSubmit} variant="contained" color="primary" size="large" type="submit" fullWidth>Dodaj</Button>
<Button variant="contained" color="secondary" size="large" onClick={clear} fullWidth>Anuluj</Button>
</form>
</Paper>
);
data.json where I have cars and models
{
"cars":[
{
"brand":"BMW",
"models":[
"Seria 1",
"Seria 2",
"Seria 3",
"Seria 4",
"Seria 5",
"Seria 6",
"Seria 7",
"Seria 8"
]
},
{
"brand":"Audi",
"models":[
"A1",
"A2",
"A3",
"A4",
"A5",
"A6",
"A7",
"A8"
]
}
],
}
Upvotes: 0
Views: 952
Reputation: 15923
That's because in case the user selected car brand does not exist in data.cars
, and .find()
returns undefined
, then you try to read .models
of undefined
which gives you an error
One option is you can have a ternary operator to check if find returns an array, then get the models like below (replace BMW
with e.target.value
)
data.cars.find(car => car.brand === "BMW") ? data.cars.find(car => car.brand === "BMW").models : []
Concept Working eg
var data = {
"cars": [{
"brand": "BMW",
"models": [
"Seria 1",
"Seria 2",
"Seria 3",
"Seria 4",
"Seria 5",
"Seria 6",
"Seria 7",
"Seria 8"
]
},
{
"brand": "Audi",
"models": [
"A1",
"A2",
"A3",
"A4",
"A5",
"A6",
"A7",
"A8"
]
}
]
}
console.log(data.cars.find(car => car.brand === "sd") ? data.cars.find(car => car.brand === "sd").models : []);
console.log(data.cars.find(car => car.brand === "BMW") ? data.cars.find(car => car.brand === "BMW").models : []);
Upvotes: 1