1
votes

Retour de la fonction de requête imbriquée Axios

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


4 commentaires

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 de getNextImageData () 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?


3 Réponses :


0
votes

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
  }
}


1 commentaires

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



1
votes

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é?


0 commentaires

4
votes

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
    })
}


0 commentaires