Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

  1. #1
    Membre du Club
    Requête axios imbriquées dans un endpoint de mon serveur
    Bonjour,
    dans mon serveur nodejs, j'ai une fonction qui doit appeler une API externe.

    L'objectif est de 1) récupérer tous les items, 2) pour chaque item, récupérer des données d'historique supplémentaires en faisant une nouvelle requête axios.

    Voila ce que j'essaie de faire

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
     
    app.get('/api/items',async function(req, res) {
     
        var url=`${API}/resources/items;
     
        axios.get(url)
            .then(response => {    
              var results = [];      
              response.data.entities.forEach(function(el){            
                var itemId = util.getJobId(el);
                getHistory(itemId).then(res => function(res){
                  console.log(res);
                  Array.prototype.push.apply(el, res);
                  console.log(el)
                  results.push(el);
                });
              });
                res.send(results);
            })
            .catch(error => {
              console.log(error);
            });
      });
     
    async function getHistory(uid) {
      try {
        var url_history=`${API}/resources/${uid}/history/`;
          let res = await axios({
              url: url_history,
              method: 'get',
              timeout: 8000,
              headers: {
                  'Content-Type': 'application/json',
              }
          })
          return res.data.entities[0]
      }
      catch (err) {
          console.error(err);
      }
    }


    Pour chaque item, à l'aide de son id, je souhaite récupérer ces informations d'historique(donc au sein d'une boucle je fais des requêtes getHistory) et rajouter ces datas à l'element existant. Puis mettre tous les éléments dans un tableau results ( Ainsi pour chaque item j'aurai les données de base + les données de son historique)
    Or au final, mon res.send(results) renvoie un tableau vide

    Auriez vous une idée ??
    Merci par avance

  2. #2
    Membre du Club
    Bonjour,
    j'ai finalement trouvé la solution.
    Je pense que le probleme venait tout simplement du foreach() qui ne doit pas être utilisée lorsqu'on fait appel a des méthodes asynchrone à l'intérieur. Il vaut mieux privilégier for(cosnt i of data) ou map() (plus performant que le for d'ailleurs sur mon cas)

    J'en ai quand même profité au passage pour remettre un peu mon code au propre et séparer les fonctions dans des fichiers js différents.

    Voici mon code final

    Côté servers.js
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    var api = require('./api')
    //récupération de tous les items
    app.get('/api/items', function(req, res) {
        api.getItems()
        .then(function(results){        
            res.send(util.parseAllResults(results))
        }).catch(function(err){
            console.log("ERR "+err)
            res.send("ko")
        })
      });


    Dans mon fichier api.js:

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
     
    exports.getItems = async function(){
     
        var items= []
        //url api externe
        var url=`${API_VP}/xxxxxxxxxx`;
     
        /récupération de tous les items
        let response = await axios.get(url);
     
        //beaucoup plus rapide le map car fait en // les requêtes
        await Promise.all(response.data.entities.map(async item=> {
            var itemid = util.getItemId(item)
            let history = await getHistory(itemid )
            Array.prototype.push.apply(job, history)
            jobs.push(job)
     
        }));
     
        return jobs;
    }
    async function getHistory(uid) {
        try {
            var url=`${API_VP}/resources/${uid}/history/`;
            let res = await axios.get(url)
            return res.data.entities[0]
        }
        catch (err) {
            console.error(err);
        }
      }

###raw>template_hook.ano_emploi###