Mariam Mahmoud
Mariam Mahmoud

Reputation: 5

Axios fetch data

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

Answers (2)

Matt U
Matt U

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

Brian
Brian

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

Related Questions