Daniel Williams
Daniel Williams

Reputation: 53

How to render a table from axios GET requests?

I'm attempting to render a table of stats from an NBA API. I'm using redux to store the user's selected players and requesting the API through my Table component. I retrieve the stats appropriately however it ends up infinitely requesting the API. I know that me setting a hook within an asynchronous request will cause this behavior but I'm not sure of a workaround at the moment. I think this is a lifecycle error, should I try using useEffect and have the player object from the redux store in the dependency array? Any input would be great. I'll post the code below.

Here's a screengrab of the behavior and console log when I log cData: https://i.sstatic.net/zeaFB.jpg

Table.js

const DataTable = () => {
  const [completeData, setCompleteData] = React.useState([]);
  const players = useSelector(state => state.players);
  var cData = [];

  const search = async val => {
    try {
      const res = await axios(
        `https://www.balldontlie.io/api/v1/season_averages?player_ids[]=${val}`
      );
      const responseData = res.data.data;
      console.log(responseData);
      return responseData;
    } catch (err) {
      console.log(err);
    }
  };

  return (
    <div>
      <h3>2019-2020 Season Averages</h3>

      <Table responsive>
        <thead>
          <tr>
            <th>Player</th>
            <th>Points</th>
            <th>Assists</th>
            <th>Rebounds</th>
            <th>Steals</th>
            <th>Blocks</th>
            <th>Turnovers</th>
          </tr>
        </thead>
        <tbody>
          {Object.keys(players).map(function(item, i) {
            var currentPlayerData = {};
            currentPlayerData = search(players[item])
              .then(result => {
                cData = JSON.parse(JSON.stringify(result[0]));
                console.log(cData);
                setCompleteData(old => [...old, cData]);

                // setCurrentData(cData);
              })
              .catch(err => {
                console.log(err);
              });
          })}
          {completeData &&
            completeData.map(function(item, i) {
              console.log(item);
              return (
                <tr key={i}>
                  <td>{item.id}</td>
                  <td>{item.pts}</td>
                  <td>{item.ast}</td>
                  <td>{item.reb}</td>
                  <td>{item.stl}</td>
                  <td>{item.blk}</td>
                  <td>{item.turnover}</td>
                </tr>
              );
            })}
        </tbody>
      </Table>
    </div>

Upvotes: 0

Views: 3964

Answers (1)

Arpit Bhatia
Arpit Bhatia

Reputation: 173

Try this approach (assuming that you want to get data from NBA API as soon as your component loads).

When your table component loads, in componentDidMount() call a method for example call this.getNBAdata()in your action.js which will get the data from API. Once you receive the data in .then() you should dispatch an action with payload data to the reducer, which can we used by adding mapStatetoProps() your table component, so once you receive the data in your props variables it will reload/refresh that particular component and by the help of .map() you shall be able to display the data in table.

Action.js sample request:

export const getNBAData = () => {
  return (dispatch) => {

Axios.get("http://nbadataendpoint.com")
  .then(response => {
    //you will get the data in response object
    dispatch({ type: 'YOUR_SUCCESS', payload: 'SOME_VALUE' });
  })
  .catch(error => {
      dispatch({ type: 'UNAUTHORISED', payload: 'SOME_VALUE'});
    }
  });
 }
};

Upvotes: 1

Related Questions