Reputation: 463
I'm working on a project that requires me to pass data to two functional components.
My axios call to the API seems to work, as well as setting the state with hooks, but I keep receiving these two errors:
Cannot convert undefined or null to object
I tried checking if the array is empty but that didn't seem to solve the problemsummaryMetrics
is not defined - This I don't understand because summartMetrics
is defined. Could it be that the elements are being displayed before the data is fetched ? Here are the files in a codesandbox Included the API's so people can see the structure of how the JSON is being returned. Im not sure if I'm passing and mapping the data correctly.
Here are the files in a codesandbox
Any help is very much appreciated
Upvotes: 0
Views: 796
Reputation: 3714
Since your state has this form :
const [summary, setSummaryData] = useState({
summaryMetrics: null,
platformsData: null
});
...you should access your state like this :
<SummaryMetrics
uniqueSocialMediaPost={summary.summaryMetrics[0]["uniqueSocialMediaPost"]}
positiveScore={summary.summaryMetrics[0]["positiveScore"]}
riskScore={summary.summaryMetrics[0]["riskScore"]}
/>
[...]
Note the "summary." before "summaryMetrics" :
summary.summaryMetrics[0]["uniqueSocialMediaPost"]
Fixed Fixed Code Sandbox (other things seems to go wrong though, white screen, but syntax error is fixed) :
Previous errors were :
Chrome dev tools is your friend when nothing happens as expected :).
By the way you could just
summary.summaryMetrics.map(s => <SummaryByPlatform summaryMetrics={s} />)
...instead of gettings keys, and you could simply pass whole summaryMetrics object to SummaryByPlatform and have only one props. But that's another subject.
Good luck with it.
Upvotes: 1
Reputation: 7080
There are several problems:
summaryMetrics
is indeed not defined. It was actually defined as summary.summaryMetrics
.summary.summaryMetrics[0][...]
will cause another "undefined error", because it was defined with default value of null
.No further explanation needed.
useEffect
in React functional component will only be run after the component is being rendered.
This means that when you execute summary.summaryMetrics[0][...]
, summary.summaryMetrics
is actually null
because you defined it as the default value. Therefore, the steps behind will generate another error because null[0]
is not possible.
What you need to do is to check whether each object properties down the tree is actually a valid object before you call the property. Otherwise, the error will happen down the property tree.
I can't show you how to correct your code, because I would need to change a big part of you code. What you can try is to mainly check the presence of values of summary.summaryMetrics
first, before calling it's children properties.
Upvotes: 0
Reputation: 12437
Your issue is that you're not waiting for summaryMetrics to load. It's trying to read the array before it's been fetched.
What I would do, is put the render inside a function and conditionally load it once the data is available.
So your Summary.js file would look like this:
const renderSummaryMetrics = () =>
summary &&
summary.summaryMetrics && (
<div>
<SummaryMetrics
uniqueSocialMediaPost={summary.summaryMetrics[0]["uniqueSocialMediaPost"]}
positiveScore={summary.summaryMetrics[0]["positiveScore"]}
riskScore={summary.summaryMetrics[0]["riskScore"]}
/>
{Object.keys(summary.summaryMetrics) &&
Object.keys(summary.summaryMetrics).length > 0
? Object.keys(summary.summaryMetrics).map(keyName => (
<SummaryByPlatform
platform={keyName}
mean_sentiment={summary.summaryMetrics[keyName].mean_sentiment}
post_count={summary.summaryMetrics[keyName].post_count}
positive_posts={summary.summaryMetrics[keyName].positive_posts}
negative_posts={summary.summaryMetrics[keyName].negative_posts}
/>
))
: null}
</div>);
return renderSummaryMetrics();
Upvotes: 0