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
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div class="container"></div>
<script type="module" src="app.mjs"></script>
</body>
</html>
Créer un module quizz.mjs
quizz.js
let quizz;
(async () => {
const url = "https://opentdb.com/api.php?amount=100";
const response = await fetch(url);
quizz = await response.json();
})();
export { quizz };
Une autre écriture (sans l'exécution immédiate de la fonction anonyme) serait
quizz.js
let quizz;
const run = async () => {
const url = "https://opentdb.com/api.php?amount=100";
const response = await fetch(url);
quizz = await response.json();
};
run();
export { quizz };
Créer un fichier app.mjs
app.js
import { quizz } from "./quizz.mjs";
function render(quizz) {
if (!quizz) {
throw "The questions list is not available";
}
const list = quizz.results
.map((question) => {
return `<li data-answer="${question.correct_answer}">${question.question} </li>`;
})
.join("");
return `<ol>${list}</ol>`;
}
const container = document.querySelector(".container");
try {
container.innerHTML = render(quizz);
} catch (e) {
container.innerHTML = e;
}
👹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
let quizz;
export default (async () => {
const url = "https://opentdb.com/api.php?amount=100";
const response = await fetch(url);
quizz = await response.json();
})();
export { quizz };
Modifiez le module app.mjs
app.js
import promise, { quizz } from "./quizz.mjs";
function render(quizz) {
if (!quizz) {
throw "The questions list is not available";
}
const list = quizz.results
.map((question) => {
return `<li data-answer="${question.correct_answer}">${question.question} </li>`;
})
.join("");
return `<ol>${list}</ol>`;
}
promise.then(() => {
let container = document.querySelector(".container");
try {
container.innerHTML = render(quizz);
} catch (error) {
container.innerHTML = error;
}
});
🥷Lancez live-server !
🆒Pour voir les réponse, nous ajoutons un fichier de style style.css
style.css
li:hover::after {
content: " 🖋️ " attr(data-answer)" ";
}
🥷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
const url = "https://opentdb.com/api.php?amount=100";
const response = await fetch(url);
let quizz = await response.json();
export { quizz };
Modifiez le module app.mjs
app.js
import { quizz } from "./quizz.mjs";
function render(quizz) {
if (!quizz) {
throw "The questions list is not available";
}
const list = quizz.results
.map((question) => {
return `<li data-answer="${question.correct_answer}">${question.question} </li>`;
})
.join("");
return `<ol>${list}</ol>`;
}
let container = document.querySelector(".container");
try {
container.innerHTML = render(quizz);
} catch (error) {
container.innerHTML = error;
}
Un module await de premier niveau agit comme une fonction asynchrone.
🌎https://dupontdenis.github.io/fetch-es20/