0

In my program I fetching some user data from github API and update the state but I am getting an error of can't read property of undefined. up until last point it was working fine as soon as I added new data I got an error. Below is my code and screenshot of error. Any help would be appreciated.

error::

enter image description here code:

api.js

import axios from 'axios';

var id = "YOUR_CLIENT_ID";
var sec = "YOUR_SECRET_ID";
var params = "?client_id=" + id + "&client_secret=" + sec;

function getProfile (username) {
  return axios.get('https://api.github.com/users/' + username + params)
    .then(function (user) {
      return user.data;
    });
}

function getRepos (username) {
  return axios.get('https://api.github.com/users/' + username + '/repos' + params + '&per_page=100');
}

function getStarCount (repos) {
  return repos.data.reduce(function (count, repo) {
    return count + repo.stargazers_count
  }, 0);
}

function calculateScore (profile, repos) {
  var followers = profile.followers;
  var totalStars = getStarCount(repos);

  return (followers * 3) + totalStars;
}

function handleError (error) {
  console.warn(error);
  return null;
}

function getUserData (player) {
  return axios.all([
    getProfile(player),
    getRepos(player)
  ]).then(function (data) {
    var profile = data[0];
    var repos = data[1];

    return {
      profile: profile,
      score: calculateScore(profile, repos)
    }
  });
}

function sortPlayers (players) {
  return players.sort(function (a,b) {
    return b.score - a.score;
  });
}

export default {
  battle: function (players) {
    return axios.all(players.map(getUserData))
      .then(sortPlayers)
      .catch(handleError);
  },

  fetchPopularRepos: function (language) {
    var encodedURI = window.encodeURI('https://api.github.com/search/repositories?q=stars:>1+language:'+ language + '&sort=stars&order=desc&type=Repositories');

    return axios.get(encodedURI)
      .then(function (response) {
        return response.data.items;
      });
  }
};

Results.js

import React from 'react';
import queryString from 'query-string';
import api from '../utils/api';
import { Link } from 'react-router-dom';
import PropTypes from 'prop-types';
import PlayerPreview from '../Components/PlayerPreview';

function Profile (props) {
  var info = props.info;
  console.log(info);
  return(
    <PlayerPreview avatar={info.avatar_url} username={info.login}>
      <ul className='space-list-items'>
        {info.name && <li>{info.name}</li>}
        {info.location && <li>{info.location}</li>}
        {info.company && <li>{info.company}</li>}
        <li>Followers: {info.followers}</li>
        <li>Following: {info.following}</li>
        <li>Public Repos: {info.public_repos}</li>
        {info.blog && <li><a href={info.blog}>{info.blog}</a></li>}
      </ul>
    </PlayerPreview>
  )
}

Profile.propType = {
  info: PropTypes.object.isRequired  
}

function Player (props) {
   return (
      <div>
         <h1 className='header'> {props.label} </h1>
         <h3 style={{textAlign: 'center'}}> Score: {props.score} </h3>
         <Profile info={props.profile}/>
      </div>
   )
}

Player.propTypes = {
   label: PropTypes.string.isRequired,
   score: PropTypes.number.isRequired,
   profile: PropTypes.object.isRequired
}

class Results extends React.Component {
   constructor(props) {
      super(props);

      this.state = {
         winner: {},
         loser: {},
         error: null,
         loading: true
      }
   }

   componentDidMount() {
    var players = queryString.parse(this.props.location.search);

    api.battle([
      players.playerOneName,
      players.playerTwoName
    ]).then(function (players){
      if (players === null) {
        return this.setState(function () {
          return {
            error: 'Looks like there was an error. Check that both users exist on Github.',
            loading: false,
          }
        });
      }

      this.setState(function () {
        return {
          error: null,
          winner: players[0],
          loser: players[1],
          loading: false,
        }
      });
    }.bind(this));
   }

   render () {
      var error = this.state.error;
      var winner = this.state.winner;
      var loser = this.state.loser;
      var loading = this.state.loading;

      if(loading === true){
         <p> Loading !! </p>
      }

      if (error) {
        return (
          <div>
            <p>{error}</p>
            <Link to='/battle'>Reset</Link>
          </div>
        )
      }

      return (
        <div className='row'>
          <Player
            label='Winner'
            score={winner.score}
            profile={winner.profile}
          />
          <Player
            label='Loser'
            score={loser.score}
            profile={loser.profile}
          />
        </div>
      )
    }
}

export default Results;

PlayerPreview.js

import React from 'react';
import PropTypes from 'prop-types';

function PlayerPreview (props) {
   return (
     <div>
       <div className='column'>
         <img
           className='avatar'
           src={props.avatar}
           alt={'Avatar for ' + props.username}
         />
         <h2 className='username'>@{props.username}</h2>
       </div>
       {props.children}
     </div>
   )
 }

 PlayerPreview.propTypes = {
   avatar: PropTypes.string.isRequired,
   username: PropTypes.string.isRequired,
 };

 export default PlayerPreview;
2
  • what's in console.log(info);? Commented May 10, 2018 at 20:38
  • it is saying undefined Commented May 10, 2018 at 20:41

1 Answer 1

1

Change

return(
    <PlayerPreview avatar={info.avatar_url} username={info.login}>
// some code...

to:

return(
    info ? 
       <PlayerPreview avatar={info.avatar_url} username={info.login}>
          // some code...
       </PlayerPreview> : null

So that if info object is null or undefined it doesn't render.

Sign up to request clarification or add additional context in comments.

3 Comments

Then I am getting this error : Profile(...): Nothing was returned from render. This usually means a return statement is missing. Or, to render nothing, return null.
I am getting output but in console I am getting an error. Above my code I updated screenshot of error. please look at it
As it mentioned in the log, score and label are undefined, which they are required according to propTypes. In Player check if props does not have the required arguments, it should renders null

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.