La réponse la plus proche que j'ai pu trouver était celle-ci, qui n'a pas aidé puisque j'ai besoin de setState: Comment exécuter une fonction après avoir utilisé array.map?
Je pense que la réponse devrait être simple, mais je suis assez novice en Javascript. J'essaye de déplacer le setState pour isLoading vers APRÈS avoir extrait tous les profils.
componentDidMount() {
console.log('MatchesScreen init props: ', Object.keys(this.props))
Object.keys(this.props.profile.profile.matches).map((username) => {
console.log('match', username)
url = 'https://xxxxxxx.execute-api.us-west-2.amazonaws.com/prod/profile?username=' + username
fetch(url, {
method: 'GET',
})
.then((response) => response.json())
.then((responseJson) => {
this.setState({
isLoading: false,
})
this.props.addMatch(responseJson)
})
.catch((error) =>{
console.error(error);
})
})
}
J'ai essayé diverses choses comme ajouter un .then () à la fonction de carte, mais jusqu'à présent pas de chance.
3 Réponses :
Essayez d'utiliser le modèle async / wait comme suit:
async componentDidMount() {
...
Object.keys(this.props.profile.profile.matches).map((username) => {
...
await fetch(url, {
...
puis déplacez votre méthode setState dans son propre callback, que vous pouvez appeler dans vos instructions .then () après votre fetch.
J'aime cette référence: https://alligator.io/js/async-functions/
Vous pouvez renvoyer chaque promesse dans la fonction .map () , ce qui vous laisserait avec un tableau de promesses. Une fois que vous avez cela, vous pouvez utiliser Promise.all () pour attendre que toutes les promesses du tableau se résolvent.
componentDidMount() {
console.log('MatchesScreen init props: ', Object.keys(this.props))
// Put all promises into an array
const promisesArray = Object.keys(this.props.profile.profile.matches).map((username) => {
console.log('match', username)
url = 'https://xxxxxxx.execute-api.us-west-2.amazonaws.com/prod/profile?username=' + username;
// Return each promise
return fetch(url, {
method: 'GET',
})
.then((response) => response.json())
.then((responseJson) => {
this.props.addMatch(responseJson)
})
.catch((error) =>{
console.error(error);
});
});
// Wait for all promises in array to resolve
Promise.all(promisesArray)
.then(() => {
// This will execute once all promises have resolved
this.setState({
isLoading: false,
});
})
.catch(e => console.error(e));
}
Essayez d'encapsuler Object.keys () dans une boucle while avec une instruction if à la fin.
var profilesMatched = 0;
while(profilesMatched < Object.keys(this.props.profile.profile.matches).length){
Object.keys(this.props.profile.profile.matches).map((username) => {
console.log('match', username)
url = 'https://xxxxxxx.execute-api.us-west-2.amazonaws.com/prod/profile?username=' + username
fetch(url, { method: 'GET', })
.then((response) => {response.json()})
.then((responseJson) => {
this.props.addMatch(responseJson);
profilesMatched++;
})
.catch((error) => {
console.error(error);
});
});
if(profilesMatched == Object.keys(this.props.profile.profile.matches).length){
this.setState({
isLoading: false,
})
}
}