I have component League.js
where there are 4 boxes containing League team details.
The team details are coming from this API => https://www.api-football.com/demo/api/v2/teams/league/${id}
When I click on each of the league boxes I am populating the Dropdown in my component Details.js
I won't get the team_id
of the first team in the dropdown anytime I click on each of the League boxes in League.js
in order to have the right calculation in a component called Stat.js
. To do this I make a call request to this endpoint => https://www.api-football.com/demo/api/v2/statistics/${league}/${team}
So I need to pass league_id
and team_id
as a parameter, I can get both values correctly but I am doing something wrong on how to pass the first team_id
of the team for each league.
These are the steps, I put only the relevant code. I am creating firstTeamStats
state that I am dispatching
In my actions => index.js
export const RECEIVE_FIRST_TEAM_STATS = "RECEIVE_FIRST_TEAM_STATS";
export const receivedFirstTeamStats = json => ({
type: RECEIVE_FIRST_TEAM_STATS,
json: json
});
.get(`https://www.api-football.com/demo/api/v2/teams/league/${id}`)
.then(res => {
let teams = res.data.api.teams;
dispatch(receivedFirstTeamStats(teams[0].team_id));
})
in my reducer => index.js
case RECEIVE_FIRST_TEAM_STATS:
return {
...state,
firstTeamStats: action.json,
isTeamsDetailLoading: false
};
in my League.js component
import {getTeamsStats} from "../actions";
const mapStateToProps = state => ({
firstTeamStats: state.firstTeamStats
});
const mapDispatchToProps = {
getStats: getTeamsStats,
};
const onClick = (evt, id, firstTeamStats) => {
evt.preventDefault();
getDetail(id); \\ get the team names in the Detail.js component
getStats(id, firstTeamStats); \\ get the state value for the first team in the dropdown in Detail.js component
};
<a href={`#${item.league_id}`} onClick={(e) => onClick(e, item.league_id, firstTeamStats)}
Right now firstTeamStats
in the onclick
method above returns correctly the first team state value but of the existing league and not in the one where I click which is what I want.
However I can get this correctly in the Details.js
Component, I have put {firstTeamStats}
there in the demo where I have reproduced my case => https://codesandbox.io/s/romantic-solomon-6e0sb (Use CORS Unblock Chrome extension to see )
So the question is, how can i pass {firstTeamStats}
correctly in League.js
in the method onclick
to the request getStats(id, firstTeamStats)
where {firstTeamStats}
is the state of my first team_id
of the league?
Whenever you are making an API call, it is an asynchronous event. You should always await, before using its response in the next line.
So inside getDetail()
, you are making an API call. But you haven't declared this method as async. so you are not waiting for it to complete and in the next line you are calling getStats()
method with an old data. Thats why your app will always be a step behind, than your DOM events.
One way would be to use async|await
and return the API response
from the function, instead of using dispatch.
You can also invoke the getTeamsStats()
inside the getTeamsDetailById()
after the api response is fetched, instead of invoking it inside OnClick()
event.
const onClick = (evt, id, firstTeamStats) => {
evt.preventDefault();
getDetail(id); \\ this is an async api call. you should have used await here.
getStats(id, firstTeamStats); \\ It will execute before the new stats are fetched
};
In Stats.js, you should not be strictly validating these fields to show Statistics... these are only numbers.. can also be 0 at times. so please remove these checks.
if (
teamsStatsWinHome &&
teamsStatsWinAway &&
teamsStatsDrawHome &&
teamsStatsDrawAway &&
teamsStatsLoseHome &&
teamsStatsLoseAway
) {
I have a working instance of your application... check below. https://codesandbox.io/s/charming-dewdney-zke2t
Let me know, if you need anything.