Tyler
Tyler

Reputation: 23

When looping through an array of objects I get a null value error

I am fetching data from the NHL API (using react, redux, and fetch api), and trying to display a teams roster information. When I console log the roster api response in the component, it works correctly and displays the array of objects, but when I try and loop through it, I get an error that the response in null.

Here is what the rosterList which holds the response looks like: https://gyazo.com/3f14d24b3a5bfb3610b470abedb6fcca

Here is the redux action:

// Redux action
export const getRoster = id => async dispatch => {
  try {
    setLoading();
    const res = await fetch(
      `https://statsapi.web.nhl.com/api/v1/teams/${id}?expand=team.roster`
    );
    const data = await res.json();

    dispatch({
      type: GET_TEAM_ROSTER,
      payload: data['teams'][0].roster.roster
    });
  } catch (err) {
    dispatch({
      type: TEAM_ERROR,
      payload: err.response
    });
  }
};

And the redux state:

case GET_TEAM_ROSTER:
      return {
        ...state,
        currentRoster: action.payload,
        loading: false
      };

And finally the component in which I am trying to render the list:

import React, { useEffect, useState } from 'react';
import styles from './teamroster.module.css';
import { getRoster } from '../../actions/teamActions';
import { connect } from 'react-redux';
import PropTypes from 'prop-types';

const TeamRoster = props => {
  const id = props.teamId;

  let rosterList = props.team.currentRoster;
  console.log(rosterList);

  useEffect(() => {
    props.getRoster(id);
    // eslint-disable-next-line
  }, []);

  return (
    <div className={styles.rosterContainer}>
      <p>This is the team roster</p>
      <ul>
        /*********** Error here, cannot read length of null ********/
        {!props.loading && rosterList.length === 0 ? (
          <p>No players available</p>
        ) : (
          rosterList.map((player, index) => (
            <li key={index}>{player.jerseyNumber}</li>
          ))
        )}
      </ul>
    </div>
  );
};

TeamRoster.propTypes = {
  getRoster: PropTypes.func.isRequired
};

const mapStateToProps = state => ({
  team: state.team
});

export default connect(
  mapStateToProps,
  { getRoster }
)(TeamRoster);

I can't figure out what the problem is, and would appreciate any guidance. Thanks.

Upvotes: 1

Views: 196

Answers (1)

JakeD
JakeD

Reputation: 457

rosterList.length is returning undefined because the component is rendering for the first time before rosterList is returned from the API. Add a check to ensure that rosterList exists before trying to call '.length' on it.

The code would look like this:

<ul>
    {props.loading || !rosterList ? (
      <p>No players available</p>
    ) : (
      rosterList && rosterList.map((player, index) => (
        <li key={index}>{player.jerseyNumber}</li>
      ))
    )}
</ul>

Upvotes: 1

Related Questions