0

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.

7
  • This syntax was working fine when I was using class instead of function and using CompetentDidMount instead of useEffect Commented Jun 29, 2020 at 17:15
  • Have you checked to make sure data.response is an array for certain? 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. Commented Jun 29, 2020 at 17:40
  • @RameshReddy When I do objTest[0] it works and returns the object. Commented Jun 29, 2020 at 17:41
  • Are you logging it inside a useEffect that has a dependency of [objTest]? Commented Jun 29, 2020 at 17:45

3 Answers 3

3

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

Sign up to request clarification or add additional context in comments.

4 Comments

The initial state is an array that code snipt is what the object looks like. const [objTest, setobjTest] = useState([]);
@JavascriptDeveloperMaintwo - what do get from response.data? Is it an array?
okay then all you have to do is use objTest.length && objTest[0].ClientDatabase. The array is empty in the begining. It takes some time for the data to get loaded. or you can set a non empty array as the initial value
@TheAlpha93 This works but the problem is that I am attempting to map over the objTest for a material ui element select, which is not working: <Select labelId="demo-simple-select-label" id="demo-simple-select" value={age} onChange={handleChange} > {objTest.map(myList => { return( <MenuItem key = {myList.ClientDatabase} value = {myList} > {myList.ClientName} + {myList.Site} </MenuItem> ) })} </Select>
0

Edit:

useEffect( () => console.log(objTest[0].ClientDatabase), [objTest])

4 Comments

What's wrong with overwriting the array in his case? He has an empty array and he's trying to populate it after getting the response.
Ah I didn't see him state the data.response was an array
@PavlosKaralis I added a picture of the console.log(response.data) which I believe shows that it is an array
@RameshReddy I added a picture of the console.log(response.data) which I believe shows it is an array
0

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
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.