Search code examples
javascriptreactjsreact-nativereact-hooksreact-chartjs

Where would I fetch Data from my database to update a Chart Using react-chartjs-2?


I'm trying to create a Bar Chart with data I'm getting from my database. Getting the data works fine, but updating the chart seems to be a problem. I'm trying to create a bar chart that gets my data, counts how many times each of the weekdays are presenst (the countData function) and then updates the state to reflect that in my Barchart. Here's my file:

import React, { useEffect, useState } from "react";
import $ from "jquery";
import {
  Chart as ChartJS,
  CategoryScale,
  LinearScale,
  BarElement,
  Title,
  Tooltip,
  Legend,
} from "chart.js";
import { Bar } from "react-chartjs-2";
import { withRouter } from "react-router-dom";
ChartJS.register(
  CategoryScale,
  LinearScale,
  BarElement,
  Title,
  Tooltip,
  Legend
);

export default function Daily() {
  const [state, setState] = useState({
    monday: null,
    tuesday: null,
    wednesday: null,
    thursday: null,
    friday: null,
    saturday: null,
    sunday: null,
  });

  const [chartData, setChartData] = useState({
    datasets: [],
  });
  const [chartOptions, setChartOptions] = useState();


  useEffect(() => {
    fetch('http://php_spice.test/database_handler.php', {
      method: "GET",
      headers: {
        "Content-Type": "application/json",
      }
    }).then(async (response) => {
      let data = await response.json();
      data = data.result;
      data = countData(data);
      console.log(data);
      setState({
        monday: data["monday"],
        tuesday: data["tuesday"],
        wednesday: data["wednesday"],
        thursday: data["thursday"],
        friday: data["friday"],
        saturday: data["saturday"],
        sunday: data["sunday"],
      }); 

    }).catch((error) => {
      console.log('error: ' +error);
    })
    
    setChartData({
      labels: [
        "Montag",
        "Dienstag",
        "Mittwoch",
        "Donnerstag",
        "Freitag",
        "Samstag",
        "Sonntag",
      ],
      datasets: [
        {
          label: "e",
          data: [
            state.monday,
            state.tuesday,
            state.wednesday,
            state.thursday,
            state.friday,
            state.saturday,
            state.sunday,
          ],
        },
      ],
    });
    setChartOptions({
      responsive: true,
      plugins: {
        legend: {
          position: "top",
        },
        scales: {
          xAxes: [
            {
              ticks: {
                fontColor: "white",
              },
            },
          ],
        },
        title: {
          display: true,
          text: "eh",
        },
      },
    });
    
  }, []);

  return (
    <div className="Daily">
      <Bar data={chartData} options={chartOptions} />
    </div>
  );

  function doThing(){
    
  }

  function countData(resultData) {
    let monday = 0;
    let tuesday = 0;
    let wednesday = 0;
    let thursday = 0;
    let friday = 0;
    let saturday = 0;
    let sunday = 0;
    $.each(resultData, function (index, rd) {
      switch (rd) {
        case "0":
          monday++;
          break;
        case "1":
          tuesday++;
          break;
        case "2":
          wednesday++;
          break;
        case "3":
          thursday++;
          break;
        case "4":
          friday++;
          break;
        case "5":
          saturday++;
          break;
        case "6":
          sunday++;
          break;
      }
    });
    var countedDays = {
      monday: monday,
      tuesday: tuesday,
      wednesday: wednesday,
      thursday: thursday,
      friday: friday,
      saturday: saturday,
      sunday: sunday,
    };
    return countedDays;
  }
}

This is what my chart looks like on loading the page: enter image description here

And this is the chart after saving my Daily.js in vscode: enter image description here

Only then the chart changes. I've added a dependency array to the useEffect Hook, because otherwise it would cause an infinite loop. I know this can be caused because of the setSate function in the useEfect hook, but I've already tried putting setstate, setChartData and setChartOptions in another function which is then called in fetch. That also didn't work.

How will I be able to update my chart without causing an infinite loop?


Solution

  • setChartData/setChartOptions are being called before the fetch request gathering the needed data has finished. Try to move this logic into the success callback of your fetch call.