Why is it not filling the useState whin i get the data?

I folowed tthis page: https://blog.logrocket.com/using-chart-js-react/
The data is loaded into the data and I see in console but the data is not loaded into the useState

import React, { useEffect, useState } from "react";
import budgetApi from "../api/budgetApi";
import { Bar } from "react-chartjs-2";
const BarChart = () => {
  const [chartData, setChartData] = useState({});

  useEffect(() => {
    getDataFromChart();
  }, []);

  const getDataFromChart = async () => {
    try {
      const response = await budgetApi.getByCategory();
      const data = response.data;
      setChartData({
        labels: [data.map((budget) => budget.category)],
        datasets: [
          {
            label: "Forint",
            data: [data.map((budget) => budget.total_amount)],
            backgroundColor: ["#ffbb11", "#ecf0f1", "#50AF95"],
            borderWidth: 1,
          },
        ],
      });
      console.log(chartData); //Empty!
    } catch (error) {
      console.log(error);
    }
  };
  return (
    <div>
      {
        <Bar
          data={chartData}
          options={{
            plugins: {
              title: {
                display: true,
                text: "Cryptocurrency prices",
              },
              legend: {
                display: true,
                position: "bottom",
              },
            },
          }}
        />
      }
    </div>
  );
};

export default BarChart;

I get some errors for example: can’t access property "map", nextDatasets is undefined
I think I get it because the chartData is empty.

Please help.
Thanks for the answers

>Solution :

const [chartData, setChartData] = useState({});

You’ve set your initial state to be an empty object. On your first render, you are passing that empty object to <Bar data={chartData}>. <Bar> doesn’t expect an empty object, so it throws an exception on this line of code.

You do eventually load data, but the error happened before then. So while you are waiting for the data to load you need to either not render the bar chart at all, or pass it in enough dummy data data that it can do its job. For example:

const [chartData, setChartData] = useState(null); // null is easier to check for than {}

// ...

return (
  <div>
    {!chartData ? (
      <span>Loading...</span>
    ) : (
      <Bar
        data={chartData}
        options={{
        // etc
      />

    )}
  </div>
);

console.log(chartData); //Empty!

This log statement is leading you astray. This will always show the old chart data, even though you’ve successfully set state. If you want to verify that your component is rerendering, then put your log statement in the body of the component (you will still need to fix the issue i mentioned at the top)

See this question for more information about why this log statement doesn’t work: The useState set method is not reflecting a change immediately

Leave a Reply