Search code examples
javascriptreactjsreduxuse-effectrecharts

React UseEffect data array for charts


I want to build a chart with recharts from the wins of a team that i am selecting from a dropdown.

I am using https://www.api-football.com/ to get the wins and matchs number from the date i want to pick.

The data array consumed in the chart has to be in the following format, with these objects.

day: matchs played
Team: number of victories

Example

  Data: [
    {day:16, Sao Paulo:4},
    {day:22, Sao Paulo:4},
    {day:27, Sao Paulo:7}
  ],

So here the relevant code.

This is my getTeamStats call, i do a Promise.all processing the requests from the dates. Here an example, when i select the Sao Paulo home team i am sending 3 requests to these endpoints.

https://www.api-football.com/demo/v2/statistics/357/19/2019-08-30
https://www.api-football.com/demo/v2/statistics/357/19/2019-09-30
https://www.api-football.com/demo/v2/statistics/357/19/2019-10-30

export function getTeamsStats(league, team, type, name) {
  return function(dispatch) {
    const url = "https://www.api-football.com/demo/v2/statistics";
    let dates = ["2019-08-30", "2019-09-30", "2019-10-30"];
    const getAllData = (dates, i) => {
      return Promise.all(
        dates.map(x => url + "/" + league + "/" + team + "/" + x).map(fetchData)
      );
    };

    const fetchData = URL => {
      return axios
        .get(URL)
        .then(res => {
          const {
            matchsPlayed: { total: teamsTotalMatchsPlayed },
            wins: { home: teamsStatsWinHome }
          } = res.data.api.statistics.matchs;
          const matchsPlayed = teamsTotalMatchsPlayed;
          const winHome = teamsStatsWinHome;
          const teamStats = {
            matchsPlayed,
            winHome
          };
          dispatch(receivedTeamsStat(teamStats, type, name));
        })
        .catch(e => {
          console.log(e);
        });
    };

    getAllData(dates)
      .then(resp => {
        console.log(resp);
      })
      .catch(e => {
        console.log(e);
      });
  };
}

I dispatch the teamStats object containing matchs played and wins.

dispatch(receivedTeamsStat(teamStats, type, name))

In my component this is how i try to create the data array

  const [data, setData] = useState([]);


  useEffect(() => {
    setData([...data, 'Day:' + home.matchsPlayed, selectedHomeName + ':' + home.totalCal]);
  },[home.matchsPlayed, home.totalCal, selectedHomeName]);

  console.log('data', [data]);

This is how the data looks when i select Sao Paulo

console log

My struggle is how can i push in the data array the team selected, wins, matchs played as 3 objects instead of having one single object as it is now? I want my data looking like i said on the top of the question.

  Data: [
    {day:16, Sao Paulo:4},
    {day:22, Sao Paulo:4},
    {day:27, Sao Paulo:7}
  ],

I have reproduced the case here => https://codesandbox.io/s/cool-wind-sism9 (In order to see the demo a chrome extension to unblock the CORS has to be installed, i use CORS Unblock)


Solution

  • There's quite a lot of code for one single question, I did not deep dive into, I only focused on how to set data to the correct data structure you asked for.

    To do so, you might need to change useEffect at line 57 of Details.js :

    useEffect(() => {
      setData(prev =>
        prev.concat([
          {
            day: home.matchsPlayed,
            [selectedHomeName]: home.winHome
          }
        ])
      );
    }, [home.matchsPlayed, home.winHome, selectedHomeName]);