Partage
  • Partager sur Facebook
  • Partager sur Twitter

[JS] probleme fetch

Sujet résolu
    18 janvier 2019 à 22:54:04

    Bonjour,

    je travaille sur un site web en exploitant une API Pokemon. Mon but est d'afficher dans une sélection de 20 Pokemons, pour chacun ; son image, son id et son nom. J'effectue un fetch pour accéder a la liste des Pokemons et ensuite un deuxième fetch pour accéder au infos de chacun. Les requêtes se font dans l'ordre des id mais ensuite problème l'affichage dans le DOM n'est plus dans l’ordre alors que l'affichage devrait être dans le même ordre des requêtes.

    Si quelqu'un pouvait m'aider a rétablir l'ordre de l'affichage, je serai vraiment heureux :D.

    function loadPoke() {
      fetch('https://pokeapi.co/api/v2/pokemon/')
      .then(function (response) {
        if (response.ok)
          return response.json();
        throw new Error('Response is not OK');
      })
      .then(function (data) {
        console.log(data);
        data.results.forEach(function (pokemon) {
          recupInfo(pokemon.url);
        });
      })
      .catch(function (error) {
        console.log(error);
      });
    }
    
    function recupInfo(url) {
      console.log(url);
      fetch(url)
      .then(function (response) {
        if (response.ok)
          return response.json();
        throw new Error('Response is not OK');
      })
      .then(function (data) {
        console.log(data);
        let container = document.querySelector('#container');
        let article = document.createElement('article');
        article.innerHTML = `
        <img src="${data.sprites.front_default}">
        <p>${data.id}</p>
        <p>${data.name}</p>`;
        container.appendChild(article);
      })
      .catch(function (error) {
        console.log(error);
      });
    }

    Deuxieme fetch (console.log(url)), ce sont les url qui vont être utiliser dans l'ordre pour obtenir les infos des Pokemons d'id 1,2,3,..,20 :

    Deuxième fetch(console.log(data)), les Pokemons sont affichés dans le désordre :

    Merci de votre attention.

    • Partager sur Facebook
    • Partager sur Twitter
      19 janvier 2019 à 12:44:34

      Salut, si tu veux quelque chose de simple et performant pour trier ton tableau tu peux faire quelque chose du style :

      let initialData = [{
        id: 2,
        name: 'pokém2'
      }, {
        id: 0,
        name: 'pokém0'
      }, {
        id: 3,
        name: 'pokém3'
      }]
      
      let orderedData = []
      
      /**
       * L'index du tableau correspond à l'id du pokémon
       */
      initialData.map(data => {
        orderedData[data.id] = data
      })
      
      initialData = orderedData

      l'avantage est aussi que si tu dois cliquer sur un pokémon pour avoir ses infos tu n'as pas à parcourir le tableau pour chercher son id et retrouver ses informations. Tu peux simplement faire initialData[idDuPokemon] pour avoir les infos.

      De plus il me semble normal que les résultats soient en désordre car fetch est asynchrone donc rien ne dit que la requête n°1 aura fini sont exécution avant la requête n°2.

      -
      Edité par fasteel 19 janvier 2019 à 12:50:31

      • Partager sur Facebook
      • Partager sur Twitter
        19 janvier 2019 à 13:16:06

        Salut, en effet je pensé a un problème de fonction asynchrone, mais n'en n'ayant pas trop fait j'avais du mal a l’intégrer dans mon code. Je vais maintenant voir avec le code que tu m'a donné et le ".map" si je peut ordonner tout ça. Merci pour ta  réponse.

        PS: Si quelqu'un s'y connait en fonction asynchrone, je ne refuse pas une explication.

        -
        Edité par Clmnt#1 19 janvier 2019 à 15:40:07

        • Partager sur Facebook
        • Partager sur Twitter
          19 janvier 2019 à 17:05:46

          Tu veux une explication sur le principe d'asynchrone ?
          • Partager sur Facebook
          • Partager sur Twitter
            19 janvier 2019 à 17:47:10

            Je comprend a peu prés comment ça marche avec "async" et "await", sa serait plutôt comment l’intégrer dans mon cas ci-dessus. Ainsi les fetch successifs se ferrait uniquement lorsque le précédent est terminé, et permetrait donc l’affichage dans le DOM par ordre des requêtes (ordre d'id).
            • Partager sur Facebook
            • Partager sur Twitter
              19 janvier 2019 à 18:40:54

              Niveau performance je conseil plutôt de laisser faire l'asynchrone au chargement des données. Dans la fonction recupInfo au lieu d'afficher directement le html, sauvegarde dans une variable global les infos, html etc... En mettant en index du tableau l'id de ton pokemon, comme ça le tri sera fait. Et une fois le chargement terminé. Tu boucle sur ton tableau et tu affiche ce que tu veux ;)

              -
              Edité par fasteel 19 janvier 2019 à 18:42:37

              • Partager sur Facebook
              • Partager sur Twitter
                19 janvier 2019 à 18:56:09

                Humm je pensais que au contraire niveau performance, le fait de reprendre toutes les infos du fetch, de les mettre dans un tableau et ensuite de gérer ce tableau était plus gourmand en ressources que de prendre les infos du fetch et directement les exploiter. Bon je vais changer tout ça alors, merci. ^^
                • Partager sur Facebook
                • Partager sur Twitter
                  21 janvier 2019 à 10:16:56

                  Si tu fais un async + await, tu fais tout en synchrone. Ca veut dire qu'à 1 seconde le fetch disons, tu dois attendre 40 secondes avant de tout recevoir, alors que ton navigateur est parfaitement capable de balancer des dizaines de fetch en parallèle. Entre 2 secondes et 40, je te conseille de rester en asynchrone.
                  • Partager sur Facebook
                  • Partager sur Twitter
                  /!\ Si je cesse de répondre c'est parce que vous êtes venus poster sans avoir suivi les cours de base sur le sujet. /!\

                  [JS] probleme fetch

                  × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                  × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                  • Editeur
                  • Markdown