Module es2022

Lecture sous forme de fichier : Lecture 🖋️

Découvrir

 L'API fetch fournit une interface Javascript pour accéder et manipuler les demandes et les réponses sur un réseau. Elle est fournie par la méthode globale window.fetch() du navigateur.


🪛Mise en place

Créer un fichier index.html

index.html

  1. <!DOCTYPE html>

  2. <html lang="en">


  3. <head>

  4.   <meta charset="UTF-8">

  5.   <meta name="viewport" content="width=device-width, initial-scale=1.0">

  6.   <title>Document</title>

  7. </head>


  8. <body>

  9.   <div class="container"></div>

  10.   <script type="module" src="app.mjs"></script>

  11. </body>


  12. </html>


Créer un module quizz.mjs

quizz.js

  1. let quizz;


  2. (async () => {

  3.   const url = "https://opentdb.com/api.php?amount=100";

  4.   const response = await fetch(url);

  5.   quizz = await response.json();

  6. })();


  7. export { quizz };


Une autre écriture (sans l'exécution immédiate de la fonction anonyme) serait

quizz.js

  1. let quizz;


  2. const run = async () => {

  3.   const url = "https://opentdb.com/api.php?amount=100";

  4.   const response = await fetch(url);

  5.   quizz = await response.json();

  6. };


  7. run();


  8. export { quizz };



Créer un fichier app.mjs

app.js

  1. import { quizz } from "./quizz.mjs";


  2. function render(quizz) {

  3.   if (!quizz) {

  4.     throw "The questions list is not available";

  5.   }


  6.   const list = quizz.results

  7.     .map((question) => {

  8.       return `<li data-answer="${question.correct_answer}">${question.question} </li>`;

  9.     })

  10.     .join("");


  11.   return `<ol>${list}</ol>`;

  12. }


  13. const container = document.querySelector(".container");

  14. try {

  15.   container.innerHTML = render(quizz);

  16. } catch (e) {

  17.   container.innerHTML = e;

  18. }


👹Lancez live-server !


💡Analyse

Il semble que le module principal n'attend pas la réponse du fetch !


Correctif !

Pour résoudre ce problème, vous pouvez exporter une promesse à partir du module quizz.mjs et attendre que l'appel à l'API soit terminé avant d'utiliser son résultat.

Modifiez le module quizz.mjs

quizz.js

  1. let quizz;


  2. export default (async () => {

  3.   const url = "https://opentdb.com/api.php?amount=100";

  4.   const response = await fetch(url);

  5.   quizz = await response.json();

  6. })();


  7. export { quizz };



Modifiez le module app.mjs

app.js

  1. import promise, { quizz } from "./quizz.mjs";


  2. function render(quizz) {

  3.   if (!quizz) {

  4.     throw "The questions list is not available";

  5.   }


  6.   const list = quizz.results

  7.     .map((question) => {

  8.       return `<li data-answer="${question.correct_answer}">${question.question} </li>`;

  9.     })

  10.     .join("");


  11.   return `<ol>${list}</ol>`;

  12. }


  13. promise.then(() => {

  14.   let container = document.querySelector(".container");

  15.   try {

  16.     container.innerHTML = render(quizz);

  17.   } catch (error) {

  18.     container.innerHTML = error;

  19.   }

  20. });

🥷Lancez live-server !


🆒Pour voir les réponse, nous ajoutons un fichier de style style.css

style.css

  1. li:hover::after {

  2.   content: " 🖋️ " attr(data-answer)" "; 

  3. }

🥷lig.2 : on recherche l'attribut data-answer pour l'afficher 


Pensez à ajouter le lien dans le fichier index.html

index.html

<head>

  <meta charset="UTF-8">

  <meta name="viewport" content="width=device-width, initial-scale=1.0">

  <title>Document</title>

  <link rel="stylesheet" href="style.css">

</head>

…d


Et oui, ES2022 est là pour nous simplifier la tâche !

En particulier, nous allons utiliser le " top-level await".

🆘Dans un module, vous pouvez utiliser le mot-clé await sans placer une déclaration à l'intérieur d'une fonction asynchrone.


Modifiez le module quizz.mjs

quizz.js

  1. const url = "https://opentdb.com/api.php?amount=100";

  2. const response = await fetch(url);

  3. let quizz = await response.json();


  4. export { quizz };


Modifiez le module app.mjs

app.js

  1. import { quizz } from "./quizz.mjs";


  2. function render(quizz) {

  3.   if (!quizz) {

  4.     throw "The questions list is not available";

  5.   }


  6.   const list = quizz.results

  7.     .map((question) => {

  8.       return `<li data-answer="${question.correct_answer}">${question.question} </li>`;

  9.     })

  10.     .join("");


  11.   return `<ol>${list}</ol>`;

  12. }


  13. let container = document.querySelector(".container");

  14. try {

  15.   container.innerHTML = render(quizz);

  16. } catch (error) {

  17.   container.innerHTML = error;

  18. }


Un module await de premier niveau agit comme une fonction asynchrone.


🌎https://dupontdenis.github.io/fetch-es20/