Reputation: 1760
I am trying get data from an api endpoint and display it on a react component.
When I am formulating components depending on the data from state.trainData
by mapping, I also require to get data from another api endpoint for each of the elements of state.trainData
.
I am using a helper function to fetch me data but thats where i hit a roadblock. I do get the data fine but the problem is I can not get it out on a variable or so to place it in a component.
In the render function after the call of getSpecificTrainDetails
, I got the data on response.data
. I have been trying for two hours to figure out how to take the data and place it in the desired component but I reached nowhere! Help would be very much appreciated.
componentDidMount = () => {
axios.get('https://rata.digitraffic.fi/api/v1/live-trains?station=SLO')
.then((response) => {
//console.log(response.data);
this.setState({
trainData: response.data,
});
}).catch((error) => {
console.log(error);
});
}
getSpecificTrainDetails = (trainNum, date) => {
let apiLink = "https://rata.digitraffic.fi/api/v1/compositions/";
let apiConstructedLink = apiLink + trainNum + "?departure_date=" + date;
return axios.get(apiConstructedLink)
.then((response) => {
return response;
}).catch((error) => {
console.log(error);
});
}
render(){
let content = this.state.trainData.map((item, i) => {
this.getSpecificTrainDetails(item.trainNumber, item.departureDate).then((response) => {
console.log(response.data);
});
return <Popup key={i}
<Card> //VALUE FROM 1ST API GOES HERE!!! </Card>
// VALUE FROM 2ND API GOES HERE!!
</Popup>;
});
}
For example from the 1st api i get the trains number and date and with this date and number passed along to the 2nd api i get the trains details.
Upvotes: 2
Views: 7358
Reputation: 3627
You should never, ever call anything asynchronous in the render
function.
What you should do instead is to call the getSpecificTrainDetails
inside of the componentDidMount
method:
componentDidMount = () => {
axios.get('https://rata.digitraffic.fi/api/v1/live-trains?station=SLO')
.then((response) => {
const trainData = response.data;
// For each train data, fetch it's specific details
const promises = trainData.map((item, i) => {
return this.getSpecificTrainDetails(
item.trainNumber,
item.departureDate
).then((trainResponse) => {
// Create a new object with both
// item's regular data and it's specific data
return {
idx: i,
item,
specificDetails: trainResponse.data
};
});
});
// Await on all promises
return Promise.all(promises);
}).then((trainsData) => {
// When all results have arrived, put them into the component's state
this.setState({
trainData: trainsData
});
}).catch((error) => {
console.log(error);
});
}
getSpecificTrainDetails = (trainNum, date) => {
let apiLink = "https://rata.digitraffic.fi/api/v1/compositions/";
let apiConstructedLink = apiLink + trainNum + "?departure_date=" + date;
return axios.get(apiConstructedLink)
.then((response) => {
return response;
}).catch((error) => {
console.log(error);
});
}
render() {
if (!this.state.trainData) {
return;
}
// This will render once all the specific results have been fetched
return this.state.trainData.map((item, i) => {
return (
<Popup key={i}>
<Card>
1st API call data:
{ item.item.something }
</Card>
2nd API call data:
{ item.specificDetails.something }
</Popup>
);
});
}
Upvotes: 2