Fetching data from API I'm getting such data:
0: {name: "bulbasaur", url: "https://pokeapi.co/api/v2/pokemon-species/1/"}
1: {name: "ivysaur", url: "https://pokeapi.co/api/v2/pokemon- species/2/"}
2: {name: "venusaur", url: "https://pokeapi.co/api/v2/pokemon-species/3/"}
3: {name: "charmander", url: "https://pokeapi.co/api/v2/pokemon-species/4/"}
4: {name: "charmeleon", url: "https://pokeapi.co/api/v2/pokemon-species/5/"}
5: {name: "charizard", url: "https://pokeapi.co/api/v2/pokemon-species/6/"}
In order to get more detailed information I need to fetch each url. I'm trying to do it with Promise.all and update state, but code doesn't work:
class App extends Component {
constructor(props) {
super(props);
this.state = {
pokemons: [],
names: [],
isLoaded: false
};
}
componentDidMount() {
this.loadPokemons();
this.loadPokemonAdditionalInfo();
}
loadPokemons() {
fetch('https://pokeapi.co/api/v2/pokemon-species')
.then(res => res.json())
.then(json => {
this.setState({
isLoaded: true,
names: json.results
})
})
}
loadPokemonAdditionalInfo() {
Promise.all(this.state.names.map(name =>
fetch(name.url)
.then(results => results.forEach(result => result.json())
.then(r => {
this.setState({
pokemons: [...this.state.pokemons, r]
})
}))))
}
}
Please advise what I'm doing wrong.
Firstly, when you attempt to load the additional data, the names won't have finished.
Just make your componentDidMount
function async and await each call (also make sure you're returning a promise for each one).
async componentDidMount(){
await this.loadPokemons();
await this.loadPokemonAdditionalInfo();
}
Also you are returning the iteration of the results, not an array of each result's json.
Replace results.forEach(result => result.json())
with:
results.map(result => result.json())
in loadPokemonAdditionalInfo
const results = [{ name:'John' }, { name:'Jane' }];
console.log('forEach', results.forEach(result => result.name));
console.log('map', results.map(result => result.name));