J'essaie d'obtenir des données d'image à partir d'une API et. Pour ce faire, je dois d'abord obtenir son identifiant, puis l'utiliser pour obtenir l'image. Pour maintenir un code propre, j'utilise une fonction pour le faire, j'ai des problèmes lorsque j'essaye de renvoyer la réponse au composant que j'appelle la fonction.
getNextImageData p >
class MyClass extends Component { constructor(props){ super(props); this.state = { image: undefined } } async componentDidMount() { const data = await getNextImageData() this.setState({ image: data, }) } render() { // something } }
MaClasse
export const getNextImageData = () => { const apiToken = lscache.get('apiToken') return( axios({ method: 'get', url: 'https://myapiurl/images/', params: { limit: '1', doc_cat: '' }, responseType: 'json' }) .then(response => { lscache.set('imageData', response, 30) axios({ method: 'get', url: 'https://myapiurl/images/' + response.data[0].id + '/', }) .then(response => { return(response.data) }) }) ) }
Je ne reçois rien du retour, lorsque j'ai collé le code directement dans mon composant, cela a bien fonctionné, mais je veux l'utiliser dans une fonction
3 Réponses :
Vous devez définir l'état une fois que toutes les données sont prêtes.
donc vous définissez l'état à l'intérieur du dernier appel axios.
Vous pouvez également le faire avec un callbackHandler ou quelque chose de similaire à keep votre code propre.
class MyClass extends Component { constructor(props){ super(props); this.state = { image: undefined } } async componentDidMount() { const nextImageResponse = await getNextImageData() // If your first response is success make the next call if( nextImageResponse.hasOwnProperty('data') ){ lscache.set('imageData', response, 30) axios({ method: 'get', url: 'https://myapiurl/images/' + nextImageResponse.data[0].id + '/', }) .then(response => { if( response.hasOwnProperty('data'){ this.setState({ image: response.data, nextImage: nextImageResponse.data }); } }) } } render() { // something } }
Merci d'avoir répondu. Mais comme je l'ai dit, si j'utilise mon code directement dans le composant, cela fonctionne aussi. Ce que je veux faire, c'est utiliser un appel de fonction pour rendre le code aussi propre que possible, en utilisant la logique axios en dehors du code du composant
Essayez ceci:
export const getNextImageData = async () => { const apiToken = lscache.get('apiToken') const data = await axios({ method: 'get', url: 'https://myapiurl/images/', params: { limit: '1', doc_cat: '' }, responseType: 'json' }); const firstResponse = await data; // // set local storage lscache.set('imageData', firstResponse, 30) const second = await axios({ method: 'get', url: 'https://myapiurl/images/' + firstResponse.data[0].id + '/', }); const thirdResponse = await second.data; return thirdResponse; }
Cela a-t-il fonctionné?
Je l'ai mal emboîté, vous n'utilisez pas un puis
dans un autre puis
, vous les utilisez au même niveau. Et chaque appel axios suit une instruction return
. Pour ce faire, je n'ai même pas eu besoin d'utiliser async / await, j'ai utilisé une autre promise
.
class MyClass extends Component { constructor(props){ super(props); this.state = { image: undefined } } componentDidMount() { getNextImageData() .then(data => { this.setState({ image: data, }) }) } render() { // something } }MaClasse
export const getNextImageData = () => { const apiToken = lscache.get('apiToken') return axios({ method: 'get', url: 'https://myapiurl/images/', params: { limit: '1', doc_cat: '' }, responseType: 'json' }) .then(response => { lscache.set('imageData', response, 30) return axios({ method: 'get', url: 'https://myapiurl/images/' + response.data[0].id + '/', }) }) .then(response => { return response.data }) }
votre fonction getNextImageData ne renvoie pas la promesse que vous essayez d'attendre d'axios .. essayez d'ajouter une instruction return avant: return axios ({méthode: 'get' ....
@jure malheureusement, je l'ai déjà essayé, je l'ai supprimé car je pensais qu'il interférait avec le retour de fonction. Mais comme cela peut prêter à confusion, je modifierai ma question, merci
De cette façon, cela ne fonctionnera pas. Au lieu de cela, retournez une
promesse
degetNextImageData ()
puis résolvez cette promesse dans votre composant.@TheCoder Je peux résoudre la dernière
promesse
dans mon composant, ok. Mais j'ai deux promesses imbriquées, comment pourrais-je faire ça? Résoudre deux requêtes imbriquées dans le composant? Diviser ces deux appels axios en deux fonctions différentes?