1

I'm quite new to the whole idea of promises and also new to react so the mix of these two have left me with this issue.

I'm using react.js with axios in a React Component. I am consuming an external API for football fixtures. I am getting all of today's fixtures looping through them to find previous fixtures between the two teams and their results to get an average score as a way to predict what the score may be.

In my constructor I have the following to set up an Axios instance

constructor(props) {
    super(props);

    // the api key for consuming api
    this.apiKey = "xxxxxxxxxxxx";

    // setup axios instance
    this.instance = axios.create({
        baseURL: 'http://api.football-data.org/v1',
        headers: {
            'X-Auth-Token': this.apiKey
        }
    });

    //Holds response from API request
    this.state = {
        // all valid fixtures
        fixtures: []
    };
}

On my componentDidMount() function, I call the fixtures route to get all of today's fixtures and loop through them, finding the fixture id, then calling another function getHead2Head(), which is where I am having my issue as the value it returns is Promise {<pending>} with [[PromiseValue]] object containing what I need.

componentDidMount() {
  let self = this;
  // call fixtures routes with timeframe of 1 day
  this.instance.get('/fixtures?timeFrame=n1').then((fixtures) => {
    // get all fixtures
    const allFixtures = fixtures.data.fixtures;
    // create valid fixtures array to add all fixture details to pass to fixtures state
    let validFixtures = [];
    // loop through all fixture objects in allFixtures array
    for (var i = 0; i < (allFixtures.length); i++) {
      // check if valid fixture, returns true or false
      let isValid = self.isValid(allFixtures[i]);
      // if fixture is valid
      if (isValid) {
        // get id of fixture to pass through to fixture route with id query
        let fixtureId = allFixtures[i]._links.self.href.split('v1/').pop();
        // home teams name
        let homeTeam = allFixtures[i].homeTeamName;
        // away teams name
        let awayTeam = allFixtures[i].awayTeamName;
        // call head2head function to get all previous results from the two teams playing
        let h2hAvgScores = self.getHead2Head(fixtureId, homeTeam, awayTeam);
        // this returns Promise {<pending>} with [[PromiseValue]] object containing what I need, how to get access to this to assign to valid fixtures array???
        console.log(h2hAvgScores);
        // push object with named values to fixtures array, not working as can't get correct value from h2hAvgScores???
        validFixtures.push({
          'homeTeam': homeTeam,
          'awayTeam': awayTeam,
          'homeTeamAvgScore': h2hAvgScores.homeTeamAvgScore,
          'awayTeamAvgScore': h2hAvgScores.awayTeamAvgScore
        });
      }
    }
    this.setState({
      fixtures: validFixtures
    });
  }).catch((error) => {
    console.log(error);
  });
}

Below is my getHead2Head() function, I've passed the fixture id, home team name and away team name as arguments. The fixture id is the route used in the api call to get the fixtures head to head results. I loop through each head to head meeting getting the results, passing them into an array and then getting the average of each integer in the array and returning the averages of both home and away team to be returned by to the componentDidMount() function.

getHead2Head(id, home, away) {
  let self = this;
  // creature empty arrays to later push scores from previous fixtures to.
  let homeTeamScores = [];
  let awayTeamScores = [];
  // set getAvgScores variable that get's instance of the head2head results of passed fixture
  let getAvgScores = this.instance.get(id + '?head2head=20').then((f) => {
    // get head2head value
    const h2h = f.data.head2head;
    // get head2head fixtures
    const fixtures = h2h.fixtures;
    // loop through all head2head fixtures
    for (var i = 0; i < fixtures.length; i++) {
      // returns true or false if hometeam of fixture is equal to hometeam of head2head fixture
      let sameFixture = this.sameFixture(fixtures[i], home);
      if (sameFixture) {
        // get the home and away team scores
        // returns as eg. { 'homeTeamScore': 2, 'awayTeamScore': 1 }
        let score = self.getFixtureScore(fixtures[i], home, away);
        // get home and away team scores from score object;
        let homeTeamScore = score.homeTeamScore;
        let awayTeamScore = score.awayTeamScore;
        // push home score to homeTeamScores array
        homeTeamScores.push(homeTeamScore);
        // push away score to awayTeamScores
        awayTeamScores.push(awayTeamScore);
      }
    }
    // return null if no previous head to head fixtures
    let homeTeamAvgScores = homeTeamScores.length > 0 ? homeTeamScores : null;
    let awayTeamAvgScores = awayTeamScores.length > 0 ? awayTeamScores : null;
    // gets average of all intergers in array and Math.round
    // returns as integer
    let hAvgScore = homeTeamAvgScores !== null ? self.getAvgScore(homeTeamAvgScores) : null;
    let aAvgScore = awayTeamAvgScores !== null ? self.getAvgScore(awayTeamAvgScores) : null;
    // return object to set value to getAvgScores variable
    return ({
      'homeTeamAvgScore': hAvgScore,
      'awayTeamAvgScore': aAvgScore
    });
  }).catch((error) => {
    console.log(error);
  });
  // return getAvgScores to componentDidMount
  return getAvgScores;
}

The issue I am having is that getAvgScores variable is equal to Promise {<pending>} and returning to h2hAvgScores as Promise {<pending>}. This does contain a value called [[PromiseValues]] containing the object I need.

How can I extract this object from the h2hAvgScores variable to pass h2hAvgScores.homeTeamAvgScore through to the validFixtures array?

Any help would be greatly appreciated, apologies if this is hard to follow, my js jargon isn't up to speed as much as it should be.

EDIT:

After the suggested answer I tried the then() function but I'm not sure what I'm exactly supposed to return as returning anything and referencing 'h2hAvgScores' still gives me the same result of Promise {<pending>}

let h2hAvgScores = self.getHead2Head(fixtureId, homeTeam,awayTeam).then((avg) => {
  return avg.homeTeamAvgScore;
});

Then trying to push to the validFixtures array, when trying to set state using the validFixtures array, it is then empty at this point, so I'm still a little clueless???

let h2hAvgScores = self.getHead2Head(fixtureId, homeTeam, awayTeam).then((avg) => { 
  return validFixtures.push({ 'homeTeam': homeTeam, 'awayTeam': awayTeam, 'homeTeamAvgScore': avg.homeTeamAvgScore, 'awayTeamAvgScore': avg.awayTeamAvgScore });
});
Community
  • 1
  • 1
mcclosa
  • 943
  • 7
  • 29
  • 59

0 Answers0