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.
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.
Share Improve this question edited Jun 29, 2020 at 17:33 JavascriptDeveloperMaintwo asked Jun 29, 2020 at 17:13 JavascriptDeveloperMaintwoJavascriptDeveloperMaintwo 333 silver badges9 bronze badges 7- This syntax was working fine when I was using class instead of function and using CompetentDidMount instead of useEffect – JavascriptDeveloperMaintwo Commented Jun 29, 2020 at 17:15
- Have you checked to make sure data.response is an array for certain? – Pavlos Karalis Commented Jun 29, 2020 at 17:26
- @RameshReddy I console.log(objTest[0].ClientDatabase) a 10 lines below the useEffect statement. The syntax of objTest[0].ClientDatabase returns the undefined error. – JavascriptDeveloperMaintwo Commented Jun 29, 2020 at 17:40
- @RameshReddy When I do objTest[0] it works and returns the object. – JavascriptDeveloperMaintwo Commented Jun 29, 2020 at 17:41
- Are you logging it inside a useEffect that has a dependency of [objTest]? – Pavlos Karalis Commented Jun 29, 2020 at 17:45
3 Answers
Reset to default 3You 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
Edit:
useEffect( () => console.log(objTest[0].ClientDatabase), [objTest])
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
}