Reputation: 39
I'm having problems accessing data that I pass it to a child component. This may have to do with the Promise not being resolved at the time of accessing it but that's what I don't know how to fix. What I need is to make sure the data is fully retrieved from the parent and then passed to the child component ApplicationStats.
This is the code I wrote for the parent component:
import axios from 'axios';
import ApplicationStats from './ApplicationStats';
const Apps = () => {
const [apiData, setApiData] = useState([]);
const ifaUrl= 'url1';
const orgUrl = 'url2';
const fetchData = () => {
const ifaResponse = axios.get(ifaUrl);
const orgResponse = axios.get(orgUrl);
axios.all([ifaReq, orgReq]).then(
axios.spread((...responses) => {
setApiData({
ifaResult: responses[0];
orgResult: responses[1];
});
}),
);
};
useEffect(() => {
fetchData();
}, [])
return (
<div className="card-deck"
<ApplicationStats apiData={apiData} />
</div>
);
};
This is the child component:
import React from 'react';
const ApplicationStats = ({apiData}) => {
const {ifaResult, orgResult} = apiData;
console.log(ifaResult.data);
return (
<div>Hey</div>
);
};
In the child component, if I replace console.log(ifaResult.data)
with console.log(ifaResult)
, I get this undefined and then I get the data.
What I'm trying to do is to keep my console.log(ifaResult.data)
in the child component, but I get this
I've even tried using async/await, but I feel I'm missing something important.
Upvotes: 1
Views: 1506
Reputation: 122
The issue is that you're initializing apiData
as an array, rather than an object. Here's the issue, demonstrated:
let x = [];
const { property } = x; // property === undefined!
console.log(property.data) // ERROR! Cannot find property `data` of undefined
The reason this breaks is because when Javascript checks an object for a property that doesn't exist, it returns undefined. However, when you check for a property off of undefined
, JavaScript will throw an error.
This will prevent you from getting the error, and will log undefined
to the console instead of breaking:
const [apiData, setApiData] = useState({ ifaResult: {}, orgResult: {}});
Another Contrived Example:
const x = undefined;
x.data // ERROR!
//...
const x = {}
x.data // undefined
Upvotes: 1
Reputation: 943615
Your initial value for apiData
is an empty array.
When the Ajax response arrives you replace it with an object that has a ifaResult
property.
… but by then you’ve already rendered the component using the initial data and got the error.
———
When you set the initial data for the state, make it the same shape as the data you intend to put in it later.
Upvotes: 1