Setting dynamic state data in Chart.JS + React

Viewed 1207

I'm having trouble setting the [data] in [datasets] dynamically. My code takes in data from an api and sets the state accordingly. I've console.logged the headshots, kills, shotshit, shotsfired, sniperskilled state and the result would be like [123,456,789,2,1]. When I substitue the variable like I did in the code snippet, it does not work. But, when I hardcore a value like 30, it works! Is there a way I can pass down data to my graph using reacts state? I want to pull from an API that returns data which makes this chart dynamic. I'm really stuck, please help! :(

import React, { useState, useEffect } from "react";
import axios from "axios";
import { useParams } from "react-router-dom";
import { Bar } from "react-chartjs-2";
const BarChart = () => {
  const selected = useParams();
  const [loaded, setLoaded] = useState(false);
  const [headshots, setHeadshots] = useState("");
  const [kills, setKills] = useState("");
  const [shotshit, setShotshit] = useState("");
  const [shotsfired, setShotsfired] = useState("");
  const [sniperskilled, setSniperskilled] = useState("");
  useEffect(() => {
    axios
      .get(`http://localhost:4040/profile/${selected.platform}/${selected.id}`)
      .then((res) => {
        if (loaded === false) {
          //Bar Graph
          setHeadshots(res.data.segments[0].stats.headshots.displayValue);
          setKills(res.data.segments[0].stats.kills.displayValue);
          setShotshit(res.data.segments[0].stats.shotsHit.displayValue);
          setShotsfired(res.data.segments[0].stats.shotsFired.displayValue);
          setSniperskilled(
            res.data.segments[0].stats.snipersKilled.displayValue
          );
          setLoaded(true);
        }
      })
      .catch((error) => {
        console.log(error);
      });
  }, []);

  const data = {
    labels: [
      "Headshots",
      "Kills",
      "Shots Hit",
      "Shots Fired",
      "Snipers Killed",
    ],
    datasets: [
      {
        label: "Player Statistics",
        data: ["30", kills, shotshit, shotsfired, sniperskilled],
        backgroundColor: [
          "rgba(255, 99, 132, 0.6)",
          "rgba(54, 162, 235, 0.6)",
          "rgba(255, 206, 86, 0.6)",
          "rgba(75, 192, 192, 0.6)",
          "rgba(153, 102, 255, 0.6)",
        ],
      },
    ],
  };
  if (loaded === false) {
    return loaded;
  } else {
    return (
      <div className="chart">
        <Bar
          redraw
          data={data}
          width={350}
          height={350}
          options={{
            maintainAspectRatio: true,
          }}
        />
      </div>
    );
  }
};

export default BarChart;
1 Answers

The data is in datasets must be unified . For example all have to be numbers. but one exception is possible and that is null and undefined. because you are waiting for axios call to be resolved and this progress is asynchronous your data list will empty.

one solution is to fulfill your data in axios response and set a data state and change it there:

const BarChart = () => {
  const selected = useParams();
  const [data, setData] = useState({ labels: [], datasets: [] });
  const [loaded, setLoaded] = useState(false);
  useEffect(() => {
    axios
      .get(`http://localhost:4040/profile/${selected.platform}/${selected.id}`)
      .then(res => {
        if (loaded === false) {
          //Bar Graph

          const data = {
            labels: [
              'Headshots',
              'Kills',
              'Shots Hit',
              'Shots Fired',
              'Snipers Killed',
            ],
            datasets: [
              {
                label: 'Player Statistics',
                data: [
                  res.data.segments[0].stats.headshots.displayValue,
                  res.data.segments[0].stats.kills.displayValue,
                  res.data.segments[0].stats.shotsHit.displayValue,
                  res.data.segments[0].stats.shotsFired.displayValue,
                  res.data.segments[0].stats.snipersKilled.displayValue,
                ],
                backgroundColor: [
                  'rgba(255, 99, 132, 0.6)',
                  'rgba(54, 162, 235, 0.6)',
                  'rgba(255, 206, 86, 0.6)',
                  'rgba(75, 192, 192, 0.6)',
                  'rgba(153, 102, 255, 0.6)',
                ],
              },
            ],
          };
          setLoaded(true);
          setData(data);
        }
      })
      .catch(error => {
        console.log(error);
      });
  }, []);

  if (loaded === false) {
    return loaded;
  } else {
    return (
      <div className='chart'>
        {data && (
          <Bar
            redraw
            data={data}
            width={350}
            height={350}
            options={{
              maintainAspectRatio: true,
            }}
          />
        )}
      </div>
    );
  }
};

export default BarChart;

Related