Reputation: 5
I am having trouble fetching data from my API and displaying it on my page. Sometimes the data is defined and I have no issue, but sometimes I get the error "TypeError: Cannot read property 'calls' of undefined". I am not sure if there is an issue with my useEffect or what is happening, I thought that this would wait for the data to be pulled before displaying it. Thanks in advance for the help!
import React, { useState, useEffect, useCallback } from "react";
import { Line } from "react-chartjs-2";
import AuthService from "../../services/auth.service";
import axios from 'axios';
import _, { map } from 'underscore';
const LineChart = () => {
const currentUser = AuthService.getCurrentUser();
const [data, setData] = useState();
const authAxios = axios.create({
baseURL: `http://localhost:3000`,
headers: {
'Authorization': `Bearer ${currentUser.token}`,
'Access-Control-Allow-Origin': '*',
}
});
const fetchData = async () => {
try {
const result = await authAxios.get('/call/' + currentUser.id);
setData(result.data);
} catch (err) {
console.log(err.message);
}
};
useEffect(() => {
fetchData();
}, [setData]);
return (
<>
<div className="relative bg-white p-6 rounded-lg shadow-lg">
<div className="relative bg-blueGray-100">
<h6 className="uppercase mb-1 text-xl font-semibold">
Filler Words Used Per Call
</h6>
<Line
data={{
labels: _.range(1, Object.keys(data.calls).length + 1),
datasets: [
{
label: "Phone Calls",
fill: false,
lineTension: 0.5,
backgroundColor: "rgba(75,192,192,1)",
borderColor: "rgba(0,0,0,1)",
borderWidth: 2,
data: [65, 59, 80, 81, 56],
}
]
}}
options={{
title: {
display: true,
text: "Phone Calls",
fontSize: 20,
},
legend: {
display: true,
position: "right",
},
}}
/>
</div>
</div>
</>
)
};
export default LineChart;
Upvotes: 0
Views: 245
Reputation: 5118
You do still need to remove the dependency of useEffect
. The other problem is that data
is undefined
, for some reason. The <Line>
component is probably rendering before data
has been populated.
Add conditional rendering for <Line>
such as {data && <Line data={...}>...</Line>}
. Then the Line
component will only be rendered when data
has a value.
Upvotes: 0
Reputation: 556
Render the Line
component conditionally: {data && <Line data={...} />}
Unrelated issue: You still should remove the setData
from useEffect
dependancy array, like other people suggested, but it won't address your missing data issue. You only want to fetch data once on mount, so leave the dependancy array empty.
Upvotes: 1