112 votes

Retourner les données de l'API Axios

J'essaie d'utiliser une application Node.JS pour faire et recevoir des demandes d'API. Elle effectue une requête get vers un autre serveur en utilisant Axios avec les données qu'elle reçoit d'un appel d'API qu'elle reçoit. Le deuxième extrait est lorsque le script renvoie les données de l'appel. Il va effectivement les prendre et les écrire dans la console, mais il ne les renverra pas dans la seconde API.

function axiosTest() {
    axios.get(url)
        .then(function (response) {
            console.log(response.data);
            // I need this data here ^^
            return response.data;
        })
        .catch(function (error) {
            console.log(error);
        });
}

...

axiosTestResult = axiosTest(); 
response.json({message: "Request received!", data: axiosTestResult});

Je suis conscient que c'est mal, j'essaie juste de trouver un moyen de le faire fonctionner. La seule façon d'obtenir des données est de passer par console.log, ce qui n'est pas utile dans ma situation.

4 votes

1 votes

J'ai l'impression que les gens sont allés un peu trop loin sur cette question. Fondamentalement, il manque un retour dans votre fonction axiosTest, et vous n'avez pas attendu le résultat de celui-ci. Lorsque vous travaillez avec des promesses, retournez toujours la promesse et attendez le résultat lorsque vous en avez besoin.

191voto

kingdaro Points 6248

Le problème est que l'original axiosTest() ne renvoie pas la promesse. Voici une explication étendue pour plus de clarté :

function axiosTest() {
    // create a promise for the axios request
    const promise = axios.get(url)

    // using .then, create a new promise which extracts the data
    const dataPromise = promise.then((response) => response.data)

    // return it
    return dataPromise
}

// now we can use that data from the outside!
axiosTest()
    .then(data => {
        response.json({ message: 'Request received!', data })
    })
    .catch(err => console.log(err))

La fonction peut être écrite plus succinctement :

function axiosTest() {
    return axios.get(url).then(response => response.data)
}

Ou avec async/await :

async function axiosTest() {
    const response = await axios.get(url)
    return response.data
}

5 votes

Je n'arrive pas à faire fonctionner cette fonction si la fonction axiosTest() est dans un fichier séparé de l'appel de la fonction : axiosTest().then.... quelque chose de spécial à faire dans ce cas ?

1 votes

Même chose pour moi, je voudrais que la fonction axiosTest() soit dans un fichier différent de celui de la fonction appelante. Quelqu'un a-t-il une idée à ce sujet ?

1 votes

On dirait que vous demandez simplement comment diviser votre code en fichiers séparés. Examinez l'utilisation de modules avec JavaScript

13voto

Fahad_Shovon Points 71

Vous pouvez remplir les données que vous voulez avec une simple fonction de rappel, disons que nous avons une liste nommée lst que nous voulons peupler, nous avons une fonction qui élève la liste des élèves,

const lst = [];  
const populateData = (data) => {lst.push(data)} 

maintenant nous pouvons passer la fonction de rappel à la fonction qui fait l'appel axios et nous pouvons pupuler la liste quand nous recevons des données de la réponse.

maintenant nous faisons notre fonction qui fait la demande et passe populateData comme fonction de rappel.

function axiosTest (populateData) {
        axios.get(url)
       .then(function(response){
               populateData(response.data);
        })
        .catch(function(error){
               console.log(error);
         });
}

2 votes

Merci @Fahad_Shovon ! Cela m'a pris une journée de dépannage, que j'ai résolu en utilisant votre solution.

0 votes

Vous détestez voir ça arriver les gars.

5voto

La bibliothèque axios crée un objet Promise(). Promise est un objet intégré dans JavaScript ES6. Lorsque cet objet est instancié à l'aide du mot-clé new, il prend une fonction comme argument. Cette fonction unique prend à son tour deux arguments, qui sont également des fonctions - resolve et reject.

Les promesses exécutent le code côté client et, en raison de cool Le flux asynchrone Javascript, pourrait finalement résoudre une ou deux choses, cette résolution (généralement considérée comme sémantiquement équivalente au succès d'une Promise), ou ce rejet (largement considéré comme une résolution erronée). Par exemple, nous pouvons détenir une référence à un objet Promise qui comprend une fonction qui va éventuellement retourner un objet de réponse (qui serait contenu dans l'objet Promise). Ainsi, une façon d'utiliser une telle promesse est d'attendre que la promesse se résolve en une sorte de réponse .

Vous pourriez soulever que nous ne voulons pas attendre quelques secondes pour que notre API renvoie un appel ! Nous voulons que notre interface utilisateur puisse faire les choses suivantes tandis que en attendant la réponse de l'API. Dans le cas contraire, nous aurions une interface utilisateur très lente. Alors comment gérer ce problème ?

Une promesse, c'est asynchrone . Dans une implémentation standard des moteurs responsables de l'exécution du code Javascript (comme Node, ou le navigateur commun), elle sera résolue dans un autre processus alors que nous ne savons pas à l'avance quel sera le résultat de la promesse. Une stratégie habituelle consiste alors à envoyer nos fonctions (par exemple, une fonction React setState pour une classe) à la promesse, résolue en fonction d'une sorte de condition (dépendant de notre choix de bibliothèque). Ainsi, nos objets Javascript locaux seront mis à jour en fonction de la résolution de la promesse. Ainsi, au lieu de getters et setters (dans la POO traditionnelle), vous pouvez penser à des fonctions que vous pourriez envoyer à vos méthodes asynchrones.

Je vais utiliser Fetch dans cet exemple pour que vous puissiez essayer de comprendre ce qui se passe dans la promesse et voir si vous pouvez reproduire mes idées dans votre code axios. Fetch est fondamentalement similaire à axios sans la conversion JSON innée, et a un flux différent pour la résolution des promesses (que vous devriez vous référer à la documentation axios pour apprendre).

GetCache.js

const base_endpoint = BaseEndpoint + "cache/";
// Default function is going to take a selection, date, and a callback to execute.
// We're going to call the base endpoint and selection string passed to the original function.
// This will make our endpoint.
export default (selection, date, callback) => {  
  fetch(base_endpoint + selection + "/" + date) 
     // If the response is not within a 500 (according to Fetch docs) our promise object
     // will _eventually_ resolve to a response. 
    .then(res => {
      // Lets check the status of the response to make sure it's good.
      if (res.status >= 400 && res.status < 600) {
        throw new Error("Bad response");
      }
      // Let's also check the headers to make sure that the server "reckons" its serving 
      //up json
      if (!res.headers.get("content-type").includes("application/json")) {
        throw new TypeError("Response not JSON");
      }
      return res.json();
    })
    // Fulfilling these conditions lets return the data. But how do we get it out of the promise? 
    .then(data => {
      // Using the function we passed to our original function silly! Since we've error 
      // handled above, we're ready to pass the response data as a callback.
      callback(data);
    })
    // Fetch's promise will throw an error by default if the webserver returns a 500 
    // response (as notified by the response code in the HTTP header). 
    .catch(err => console.error(err));
};

Maintenant que nous avons écrit notre méthode GetCache, voyons à quoi ressemble la mise à jour de l'état d'un composant React à titre d'exemple...

Quelques composants React.jsx

// Make sure you import GetCache from GetCache.js!

resolveData() {
    const { mySelection, date } = this.state; // We could also use props or pass to the function to acquire our selection and date.
    const setData = data => {
      this.setState({
        data: data,
        loading: false 
        // We could set loading to true and display a wee spinner 
        // while waiting for our response data, 
        // or rely on the local state of data being null.
      });
    };
  GetCache("mySelelection", date, setData);
  }

En fin de compte, on ne "retourne" pas les données en tant que telles, je veux dire qu'on peut le faire mais il est plus idiomatique de changer sa façon de penser... Maintenant, nous sommes envoi de aux méthodes asynchrones.

Bon codage !

4voto

Arman Charan Points 3545

axiosTest() est en train de tirer asynchronously et ne pas être attendu.

A then() function doit être branché par la suite afin de capturer la response variable ( axiosTestData ).

Voir Promise pour plus d'informations.

Voir Async pour monter en grade.

// Dummy Url.
const url = 'https://jsonplaceholder.typicode.com/posts/1'

// Axios Test.
const axiosTest = axios.get

// Axios Test Data.
axiosTest(url).then(function(axiosTestResult) {
  console.log('response.JSON:', {
    message: 'Request received',
    data: axiosTestResult.data
  })
})

<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.18.0/axios.js"></script>

2voto

YordanGeorgiev Points 1222

IMO règle de base extrêmement importante pour votre code js côté client est de garder séparé le traitement des données et la logique de construction de l'interface dans des fonctions différentes, ce qui est également valable pour axios data fetching ... de cette façon, votre flux de contrôle et de gestion des erreurs sera beaucoup plus simple et plus facile à gérer, comme il pourrait être vu à partir de ce qui suit ok, va chercher

et ceci Recherche de NOK

<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
    <script>

       function getUrlParams (){
          var url_params = new URLSearchParams();
          if( window.location.toString().indexOf("?") != -1) {
             var href_part = window.location.search.split('?')[1]
             href_part.replace(/([^=&]+)=([^&]*)/g,
                function(m, key, value) {
                   var attr = decodeURIComponent(key)
                   var val = decodeURIComponent(value)
                   url_params.append(attr,val);
             });
          }
          // for(var pair of url_params.entries()) { consolas.log(pair[0]+ '->'+ pair[1]); }
          return url_params ;
       }

      function getServerData (url, urlParams ){
          if ( typeof url_params == "undefined" ) { urlParams = getUrlParams()  }
          return axios.get(url , { params: urlParams } )
          .then(response => {
             return response ;
          })
          .catch(function(error) {
             console.error ( error )
             return error.response;
          })
       }

    // Action !!!
    getServerData(url , url_params)
        .then( response => {
           if ( response.status === 204 ) {
              var warningMsg = response.statusText
              console.warn ( warningMsg )
              return
           } else if ( response.status === 404 || response.status === 400) {
              var errorMsg = response.statusText // + ": "  + response.data.msg // this is my api
              console.error( errorMsg )
              return ;
           } else {
              var data = response.data
              var dataType = (typeof data)
              if ( dataType === 'undefined' ) {
                 var msg = 'unexpected error occurred while fetching data !!!'
                 // pass here to the ui change method the msg aka
                 // showMyMsg ( msg , "error")
              } else {
                 var items = data.dat // obs this is my api aka "dat" attribute - that is whatever happens to be your json key to get the data from
                 // call here the ui building method
                 // BuildList ( items )
              }
              return
           }

        })

    </script>

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X