Ralph B
Ralph B

Reputation: 27

Looping issue with a json in javascript

I was wondering what the issue with the bottom loop is or if I'm going through the last json wrong somehow when I'm trying to log it into the console. The arrays are above the given code and the first two loops work fine. I'm trying to return goals but the reality is I want to find an efficient way to return all of the stats.

     d3.json('https://statsapi.web.nhl.com/api/v1/teams', function(data) {
      for (i=0; i < 31; i++) {
          teamID.push(data.teams[i].id);
      }
  });

  console.log(teamID);

  // request roster json data from API and loop through roster to get all player IDS
  // and append them to the playerList array

  d3.json('https://statsapi.web.nhl.com/api/v1/teams/1/?expand=team.roster', function(data) {
      for (i=0; i < data.teams[0].roster.roster.length; i++) {
        playerList.push(data.teams[0].roster.roster[i].person.id);
      }
  });

  console.log(playerList);

  // request player stat json data from API and loop through all players to get all stat
  // and append them to an array

  var playerStats = [];

    for (i = 0; i < playerList.length; i++) {
        d3.json('https://statsapi.web.nhl.com/api/v1/people/' + playerList[i] + '/stats/?stats=statsSingleSeason&season=20172018', function(data) {
          console.log(data.stats[0].splits[0].stat.goals);
        });

  //      console.log(playerStats);
      };

Upvotes: 0

Views: 87

Answers (2)

HMR
HMR

Reputation: 39270

Promises (Promise.all) are not supported at all in Internet Explorer (they are in Edge) and some older versions of other browsers. Arrow functions are also not supported in these browsers.

I assume that when you need to support older browsers you can use babel (with webpack) or know how to write ES5.

d3.json returns a promise so you can leave out the callback and uses promises:

Promise.all([
  d3.json('https://statsapi.web.nhl.com/api/v1/teams'),
  d3.json('https://statsapi.web.nhl.com/api/v1/teams/1/?expand=team.roster')  
])
.then(
  ([teams,playerData])=>{
    const playerList = playerData.teams[0].roster.roster.map(
      player=>player.id
    );
    return Promise.all(
      playerList.map(
        playerID=>
          d3.json(`https://statsapi.web.nhl.com/api/v1/people/${playerID}/stats/?stats=statsSingleSeason&season=20172018`)
      )
    ).then(
      (playerStats)=>[teams,playerData,playerStats]
    )
  }
)
.then(
  ([teams,playerData,playerStats])=>{
    console.log("teams:",teams);
    console.log("playerData:",playerData);
    console.log("playerStats:",playerStats);
  }
)
.catch(
  err=>console.warn("Something went wrong:",err)
);

I did not comment on how the code works so please let me know if you have specific questions about the code. I suggest reading this if you don't know why promises are used. And google "mdn promise all" before asking what promise all does.

Upvotes: 0

th3n3wguy
th3n3wguy

Reputation: 3737

Your final loop is probably attempting to initialize / run at the same time as the HTTP calls are being returned from the APIs. Since you are using callbacks to get the details, rather than promises, then you will need to do this in callback form. Here is the best I can do without you actually showing me the full code:

d3.json('https://statsapi.web.nhl.com/api/v1/teams', function(teamResponse) {
  var teamIds = teamResponse.teams.filter((team, i) => i < 31)
    .map((team) => team.id);

  // I use the functional approach above because I think it is cleaner than loops.
  // for (i=0; i < 31; i++) {
  //    teamID.push(data.teams[i].id);
  //}

  d3.json('https://statsapi.web.nhl.com/api/v1/teams/1/?expand=team.roster', function(rosterResponse) {
    var playerIdList = rosterResponse.teams[0].roster.roster
      .map((roster) => roster.person.id);

    // Swap this out for the functional method above.
    //for (i=0; i < data.teams[0].roster.roster.length; i++) {
    //  playerList.push(data.teams[0].roster.roster[i].person.id);
    //}

    for(var i = 0; i < playerIdList; i++) {
      d3.json('https://statsapi.web.nhl.com/api/v1/people/' + playerIdList[i] + '/stats/?stats=statsSingleSeason&season=20172018', function(data) {
        console.log(data.stats[0].splits[0].stat.goals);
      });
    }
  });
});

Upvotes: 1

Related Questions