Reputation: 33
In my ClientData.js
I am using useEffect to call an API(which is working), then using useState to set the API response.data to a variable(which is working).
The response.data is an array of objects which I then set equal to a local variable. But when I attempt to access the object parameter I get a object undefined error.
I think the problem might be is that the object is undefined due to it waiting for the API response.
This is what the object from the API looks like:
objTest={
ClientDatabase: "21",
ClientID: "21",
ClientName: "21",
ClientServer: "21",
Country: "US - 21",
DatabaseVersion: "21",
Namespace: "21",
};
function SimpleSelect() {
const classes = useStyles();
const [objTest, setobjTest] = useState([]);
const clientAPI = useCallback( async() => {
//returns an array of objects
await axios({
method:'get',
url,
auth: {
username: user,
password: pass
}
})
.then(function(response) {
setobjTest( response.data)
})
.catch(function (error){
console.log(error);
});
})
useEffect( () => {
clientAPI();
}, [])
When I attempt to access the object it works using console.log((objTest[0]));
but when I attempt to access the objects parameter
like this: console.log((objTest[0].ClientDatabase));
it returns
TypeError: Cannot read property 'ClientDatabase' of undefined
This is the console log of response.data enter image description here
The response.data is an array.
Upvotes: 0
Views: 7973
Reputation: 778
You put the initial state as an empty array. That's why you can't access it's first element. you can either set a non empty array as the initial state like this
const obj=[{
ClientDatabase: "21",
ClientID: "21",
ClientName: "21",
ClientServer: "21",
Country: "US - 21",
DatabaseVersion: "21",
Namespace: "21",
}];
const [objTest, setobjTest] = useState(obj);
or you can check if the array is not empty
objTest.length && console.log(objTest[0].ClientDatabase)
The api call will take some time fetch the data. The initial state is what gives you the error
<Select labelId="demo-simple-select-label" id="demo-simple-select" value={age} onChange={handleChange} > {objTest.length && objTest.map(myList => { return( <MenuItem key = {myList.ClientDatabase} value = {myList} > {myList.ClientName} + {myList.Site} </MenuItem> ) })} </Select>
Try this out
Upvotes: 3
Reputation: 10652
The issue is with when you're logging the data. You're logging it a bit early.
So to check the modified state you can use an additional useEffect
hook.
useEffect(() => {
if(objTest.length > 0) {
console.log(objTest[0].ClientDatabase)
}
}, [objTest])
And when you want to use this in the JSX you can check if it's populated:
{
clientArrTwo.length > 0 ? <Select labelId="demo-simple-select-label"
id="demo-simple-select"
value={age}
onChange={handleChange} >
{clientArrTwo.map(myList => {
return (<MenuItem key={myList.ClientDatabase} value={myList} > {myList.ClientName} + {myList.Site} </MenuItem>)
})}
</Select> : null
}
Upvotes: 0
Reputation: 2966
Edit:
useEffect( () => console.log(objTest[0].ClientDatabase), [objTest])
Upvotes: 0