Dimisizz
Dimisizz

Reputation: 69

Cannot access object properties via props in ReactJS

I fetch data from API and pass it to Table component like this:

function MainSectionOrganization() {

    const [obj, setObj] = useState([]);

    useEffect(() => {
        fetch('http://127.0.0.1:5000/getCompanies')
        .then((response) => {
            return response.json();
        }).then((data) => {
            setObj(data);
        })
    }, []);

    return (
        <Table data={obj} />
    )
}

Then, in Table component, I try to do console.log for props.data[0] and I see data in Chrome terminal correctly.

import React from 'react';
import './Table.css';
import { useTable } from 'react-table';

function Table(props) {

    console.log(props.data[0]);
    ...

enter image description here

However, when I try to access any properties of the object, for example console.log(props.data[0].OU01_Code), I encounter an error Cannot read property '...' of undefined

I see many people have solution with class component, but for some reason I need to use function component. Can you help me on this one ?

Upvotes: 2

Views: 2595

Answers (3)

pageNotfoUnd
pageNotfoUnd

Reputation: 666

because the initial render will occur before the API call is completed you can use props.data && console.log(props.data[0]) or if you're open to use Optional chaining it would be easy even props?.data?.[0]

Upvotes: 1

David
David

Reputation: 219057

fetch is asynchronous. So the first thing the component does is get rendered with an empty array:

const [obj, setObj] = useState([]);
//...
return (
    <Table data={obj} />
)

When that happens, any reference to an element of that array would be undefined:

props.data[0]

So trying to read a property of that undefined array element would result in that exact error:

props.data[0].OU01_Code
// Cannot read property 'OU01_Code' of undefined

After fetch resolves its result and the state is updated, obj has elements (presumably) and you can access them.


Conceptually, you need to handle the situation where your array is empty. Do you want to display <Table /> at all in that case? If not, you can conditionally display it in the parent component:

return (
    <>
        {obj.length > 0 && <Table data={obj} />}
    </>
)

Or if you do want to display <Table /> with an empty array then you'll need to include logic within that component (which we can't see at this time) to handle an empty array. Basically, you need to check props.data.length before trying to access props.data[0].

Upvotes: 4

Evgeny Klimenchenko
Evgeny Klimenchenko

Reputation: 1194

Hey the problem is that you trying to access props.data[0].OU01_Code and it is not there YET, so you need to make some kind of condition to check that it is there. Try:

if (props.data && props.data[0]) {
  console.log(props.data[0].OU01_Code)
}

Let me know if it helps, cheers

Upvotes: 5

Related Questions