Reputation: 1406
I'm working with the NHL API and retrieving hockey stats for my app. The API has multiple endpoints that I'm using to access player stats.
Roster endpoint
https://statsapi.web.nhl.com/api/v1/teams/3/roster
After I retrieve this data I can access an object called person
which contains an ID number for that individual player's API endpoint that contains pedigree information (i.e. country they are from, height/weight, etc..). I can then send an API request that looks like this to retrieve more data for that individual player, in this case 8476191
is the ID number.
Pedigree Info endpoint:
https://statsapi.web.nhl.com/api/v1/people/8476191
I can also pass the ID number, 8476191
, to a stats endpoint which contains stats for the same player.
Stats endpoint:
https://statsapi.web.nhl.com/api/v1/people/8476191/stats?stats=statsSingleSeason&season=20182019
What I would like to do is send a request to the Roster endpoint
, grab the ID numbers for every player on the roster, and then make subsequent API calls to the Pedigree info endpoint
and the stats endpoint
using the ID number.
How can I make an Axios
get request to the roster endpoint and then nest two more get requests within the call that can access the ID number from the first call? Here is what I attempted:
// State for retrieving player ID numbers from roster endpoint
const [playerIDNumbers, setPlayerIDNumbers] = useState([]);
useEffect(() => {
// Get the roster data, set playerIdNumbers to an array containing all the ID numbers
axios.get(`https://statsapi.web.nhl.com/api/v1/teams/${teams[teamName].id}/roster`)
.then(res => {
setPlayerIDNumbers(Object.values(res.data.roster).map((x) => {
return x.person.id;
}));
// res now contains all the ID numbers
console.log(res);
})
// After grabbing all the ID numbers for each player on the roster, I want to map through each ID
// in the array and send a request for each player's pedigree data
.then(res => {
// Later in my code I created an array to contain the IDs called playerIDArr
playerIDArr.map((playerID) => {
axios.get(`https://statsapi.web.nhl.com/api/v1/people/${playerID}/`)
})
console.log('Player ID call returned : ' + res);
})
// After this is done I want to make a third request using the ID numbers to grab the stats /////from the stats endpoint
/* Stats Axios request would go here */
.catch(err => {
console.log('Error : ' + err);
})
}, [])
Upvotes: 2
Views: 4806
Reputation: 9814
No need to keep the state, here is how to do this using a closure:
useEffect(() => {
axios.get(`https://statsapi.web.nhl.com/api/v1/teams/${teams[teamName].id}/roster`)
// get all ids
.then(res => Object.values(res.data.roster).map((x) => x.person.id))
// map through ids and retrieve the data
.then(ids => {
const people = Promise.all(ids.map(id => axios.get(`https://statsapi.web.nhl.com/api/v1/people/${id}/`)))
const stats = Promise.all(ids.map(id => axios.get(`https://statsapi.web.nhl.com/api/v1/stats/${id}/`)))
return Promise.all([people, stats])
}).catch(err => {
console.log('Error : ' + err);
})
})
// or using async/await, and some refactoring
const getRoster = id => axios.get(`https://statsapi.web.nhl.com/api/v1/teams/${id}/roster`)
const getPerson = id => axios.get(`https://statsapi.web.nhl.com/api/v1/people/${id}/`)
const getStats = id => axios.get(`https://statsapi.web.nhl.com/api/v1/stats/${id}/`)
useEffect(() => {
const res = await getRoster(teams[teamName].id)
const ids = Object.values(res.data.roster).map(x => x.person.id)
return Promise.all(ids.map(id => Promise.all([getPerson(id), getStats(id)])))
})
Upvotes: 2