I have been having an issue with a React webapp I'm building. Because of the way the API is structured, I need to do multiple API calls to get the stats data for a searched NBA player. The first API call fetches a list of players who meet the search criteria (i.e. when you search the name "Williams" it will display a list of player IDs which you can then do another API call with for more detailed stats on the chosen player). I am having trouble rendering a list of radio buttons with names of all the players who match the search criteria: there is a delay in rendering this list - I need to do another action (i.e. a backspace or writing another character) for the list to display properly, similar to this post here: React not rendering search results from API onChange
The answer in this case says that the async/await is handled incorrectly, but I can't see the problem in my handling of the API calls.
async function findListofPlayers(searchParams) {
let playerCall = await fetch(`https://www.balldontlie.io/api/v1/players?search=${searchParams}&per_page=5`)
let playersList = await playerCall.json();
let playersArray = []
for (let i = 0; i < playersList.data.length; i++) {
playersArray.push(playersList.data[i].id)}
return playersArray}
async function submitHandler(event) {
event.preventDefault()
let currentSearch = [];
const playersArray = await (findListofPlayers(searchParams))
playersArray.forEach( async (player) =>
{let entry = await fetch(`https://www.balldontlie.io/api/v1/players/${player}`)
let result = await entry.json();
currentSearch.push(result)
})
toggleSubmitted(true)
updateSearchedPlayers(currentSearch)}
Above you see the two functions involved in retrieving a list of players who match a search criteria, ending in a returning of a list of 5 players who match the criteria. From here, the list gets passed as a prop to this functional component which renders buttons from the list the API returns:
export default function Results(props) {
const [playerList, setPlayerList] = React.useState([])
React.useEffect(() => setPlayerList(props.searchedPlayers), [props.searchedPlayers])
const playerButtons = playerList.map(x =>
<div key={x.id}>
<input
type="radio"
name="playerChoose"
onChange={props.selectPlayer}
value={x.id}
alt={`${x.first_name} ${x.last_name}`}>
</input>
<label>
{`${x.first_name} ` + x.last_name}
</label>
</div>)
return <div className="results">
<form onSubmit={props.selectPlayer} className="searchResults">
<label htmlFor="year">Season: </label>
<select
name="year"
defaultValue={currentSeason}
onChange={props.selectYear}>
{seasonDropdown}
</select>
<br></br><br></br>
<div className="playerList">
<div>
{playerButtons}
</div>
</div>
</form>
<br></br>
<div className="disclaimer"><b>Search results are limited to 5 players.</b></div>
<button onClick={props.selectPlayer}>Find Player Stats</button>
</div>
}
From my perspective, I'm awaiting the API calls to complete before moving on. In the submitHandler, there is a function which sets the state of "submitted" to true, but only after the asynchronous functions are completed (because I am awaiting them, right?), and when submitted is true that is when the radio button component will render. But that isn't the behaviour I'm getting. I'm a little confused on where to go from here - I've even tried moving the playerList state to the radio button rendering component instead of strictly passing the playerList as a prop, but that didn't do anything. Any help would be appreciated.