Utiliser l’API Notion pour créer un quiz avec JavaScript

La notion est une application multi-fonctions pour organiser toutes sortes de contenus, des notes aux calendriers et aux rappels. Dans notre dernier article, «Premiers pas avec l’API Notion et son SDK JavaScript”, nous nous sommes penchés sur l’utilisation de l’API de Notion et avons créé une petite interface pour interagir avec elle. Cet article va maintenant explorer un autre cas d’utilisation de l’API Notion : la création d’un quiz JavaScript.
Bien qu’aucune connaissance préalable ne soit nécessaire pour suivre cet article (je fournirai toutes les étapes requises), nous traiterons du code frontal et principal, car il y a un peu de configuration Node.js et Express impliquée. , donc certaines compétences JavaScript sont supposées.
Configuration du projet de quiz JavaScript
Nous allons diviser notre configuration en deux sections. Dans la première, nous allons parcourir la configuration requise du côté Notion, et dans la deuxième partie, nous travaillerons avec notre code.
Pour suivre, vous aurez besoin d’un compte Notion (plus d’informations ci-dessous), ainsi qu’une copie récente de Node installé sur votre machine. Comme toujours, le le code final du tutoriel est disponible sur GitHub.
La configuration de la notion
Si vous n’avez pas encore de compte Notion, veuillez en créer un en suivant ce lien. Après avoir créé votre compte et vous être connecté, créez une nouvelle page en choisissant Ajouter une page et donnez-lui un nom. Pour ce tutoriel, nous utiliserons un Table
base de données. Bien que ce ne soit pas la base de données idéale pour créer un quiz, c’est la plus proche que nous puissions atteindre avec Notion !
Insérer des informations dans le tableau
Maintenant que nous avons notre vide Table
nous devons comprendre comment y insérer correctement nos informations.
Notre schéma prévu pour notre quiz est le suivant :
{
"1": {
"Question": "Which is the purpose of JavaScript?",
"Answers": {
"1": "To style HTML Pages",
"2": "To add interactivity to HTML pages",
"3": "To perform server side scripting operations"
},
"Correct": "To add interactivy to HTML pages"
},
"2": {
"Question": "To insert a JavaScript into an HTML page, which tag is used?",
"Answers": {
"1": "<script="java">",
"2": "<javascript>",
"3": "<script>"
},
"Correct": "<script>"
},
"3": {
"Question": "Which of the following is correct to write “Hello World” on the web page?",
"Answers": {
"1": "print('Hello World')",
"2": "document.write('Hello World')",
"3": "response.write('Hello World')"
},
"Correct": "document.write('Hello World')"
}
}
Notion n’est pas vraiment conçu pour ce type de base de données, nous devons donc faire preuve de créativité ! 💡 Alors notre Question
colonne sera juste un Title
(qui fonctionne très bien) et notre Correct
la colonne sera de type Text
(qui fonctionne également comme prévu). Pour nos multiples options, cependant, nous devons faire quelque chose de différent ! Mon approche consiste à utiliser le Multi-select
type de champ afin que je puisse écrire plusieurs résultats dans la même cellule (nous verrons plus loin à quoi ressemblent les données récupérées). Donc notre Table
devrait ressembler à l’image suivante comme résultat final.
Création de notre intégration API Notion
Maintenant, nous devons aller à l’API Notion site Internet pour créer notre intégration. appuyez sur la Mes intégrations bouton dans le coin supérieur droit puis cliquez sur Créer une nouvelle intégration. Nous devons remplir notre titre et être sûr de choisir notre espace de travail associé (il sera choisi par défaut mais assurez-vous de cela). Si nous appuyons Soumettre, nous serons dirigés vers une nouvelle page avec un jeton d’intégration interne (nous l’utiliserons dans notre code) et avec deux cases d’option indiquant où nous voulons utiliser notre intégration. Nous n’avons rien d’autre à faire sur cette page que de copier notre jeton et d’appuyer sur Sauvegarder les modifications.
Revenons maintenant à notre espace de travail Notion. Dans notre nouvelle base de données Notion, nous voulons appuyer sur Partageralors Inviter. Nous pourrons alors choisir notre intégration nouvellement créée. Si nous le choisissons et appuyons sur Inviter, notre configuration de Notion est terminée. Bon travail! 🙌
La configuration du code
Pour la configuration de notre code, nous utiliserons un référentiel de modèles Notion (que nous pourrons ensuite utiliser sur n’importe lequel de nos projets d’API Notion !) qui contient déjà le code initial requis pour fonctionner avec l’API de Notion. Ce dépôt peut être trouvé ici, alors assurez-vous de le bifurquer et de le cloner pour accompagner notre projet ! Si vous êtes intéressé par ce que font tous les morceaux de code, veuillez vous référer à « Premiers pas avec l’API Notion et son SDK JavaScript« , puisque nous entrons dans beaucoup de détails pour chaque bit de code (le référentiel a également un README
cela devrait expliquer ce qu’il fait!).
Installation des dépendances
Après avoir forké et cloné notre référentiel de modèles Notion, notre première étape consiste à installer nos dépendances, alors assurez-vous d’exécuter yarn
ou alors npm install
sur notre terminal à l’intérieur du dossier. Dans ce projet, nous avons trois dépendances : la @notionhq/client, dotenv et Exprimer. Nous utiliserons dotenv pour gérer nos variables et les garder en sécurité (comme celle que nous avons vue sur notre intégration) et Express pour créer notre back-end et notre serveur pour notre application.
Pour gérer nos variables avec dotenv, créez un .env
fichier à la racine de notre projet et collez-y ce qui suit :
NOTION_API_KEY = YOUR_TOKEN_HERE
NOTION_API_DATABASE = YOUR_DATABASE_ID_HERE
Notre NOTION_API_KEY
est la clé que nous pouvons trouver dans notre Intégrationset notre NOTION_API_DATABASE
peut être trouvé en accédant à la page Notion créée et en regardant la barre d’URL du navigateur. Il vient après le nom de votre espace de travail (si nous en avons un) et la barre oblique (myworkspace/
) et avant le point d’interrogation (?
). L’ID comporte 32 caractères, contenant des chiffres et des lettres :
https://www.notion.so/myworkspace/a8aec43384f447ed84390e8e42c2e089?v=...
|--------- Database ID --------|
Si nous craignons d’avoir les clés API de Notion sur un fichier de notre référentiel, notez que sur notre .gitignore
nous avons le .env
déposez-y; la .gitignore
nous permet de mettre différents noms de fichiers/dossiers à l’intérieur, ce qui signifie que ces fichiers/dossiers ne seront pas ajoutés à notre dépôt lorsque nous pousserons notre code.
Maintenant que nous avons notre référentiel initial et que nous avons les informations d’identification requises de Notion, nous pouvons commencer à travailler sur notre quiz !
Saisir les données du quiz JavaScript
Nous devons d’abord vérifier si nous sommes bien connectés à notre base de données Notion, nous allons donc accéder à notre .index.js
déposer et enregistrer notre reponse
variable (voyez comment nous récupérons notre databaseId
de notre .env
fichier et l’utiliser sur notre requête de base de données?).
Si nous courons ensuite yarn start
nous devrions voir quelque chose comme la capture d’écran suivante sur notre terminal.
Voir cela sur notre terminal signifie que nous sommes correctement connectés à notre base de données Notion et que nous pouvons maintenant obtenir les données requises. Notre getDatabase
la fonction ressemblera à ceci :
exports.getDatabase = async function () {
const response = await notion.databases.query({ database_id: databaseId });
const responseResults = response.results.map((page) => {
return {
id: page.id,
question: page.properties.Question.title[0].plain_text,
answers: page.properties.Answers.multi_select,
correct: page.properties.Correct.rich_text[0].plain_text,
};
});
return responseResults;
};
Avec responseResults
nous cartographions sur notre results
(correspondant aux entrées de notre base de données) et nous mappons les chemins des différentes propriétés aux noms que nous choisissons (dans ce cas, id
, question
, answers
et correct
). Remarquez à quel point le chemin de l’objet est spécifique. C’est par conception, ce qui signifie que, lors du développement et de l’utilisation de votre propre base de données, vous devez rechercher en permanence les propriétés renvoyées jusqu’à ce que vous trouviez les informations que vous recherchez (c’est vraiment une question d’essais et d’erreurs).
Avec ce nouveau code, nous appelons pratiquement notre API et sélectionnons les propriétés que nous voulons utiliser dans notre code, ce qui signifie que nous sommes prêts à travailler avec elles sur notre interface !
Affichage de nos données dans le navigateur
Commençons par traiter de notre HTML et CSS, car ils sont assez directs ! Nous ne ferons aucun changement sur notre code HTML à partir du modèle, et sur notre style.css
nous pouvons coller le code suivant sous celui existant :
.questionContainer {
padding: 30px;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
box-shadow: rgba(149, 157, 165, 0.2) 0px 8px 24px;
border-radius: 10px;
}
.numberElement {
margin: 0px auto 10px;
font-size: 12px;
font-weight: 700;
text-transform: uppercase;
}
.question {
margin: 0px auto 40px;
}
.answersDiv {
width: 100%;
display: flex;
flex-direction: column;
gap: 20px;
}
.answerOption {
padding: 20px;
margin: 0px;
font-size: 18px;
text-align: center;
cursor: pointer;
border: 1px solid rgb(42, 43, 44);
border-radius: 40px;
}
Nous ne verrons pas encore ces changements de style, mais nous pouvons maintenant nous concentrer sur la fonctionnalité, qui est la partie la plus importante de ce didacticiel.
Si nous passons maintenant au main.js
fichier à l’intérieur du public
dossier, nous verrons que nous récupérons déjà nos données de notre back-end avec le getDataFromBackend
une fonction. Si vous êtes confus par cela, « Premiers pas avec l’API Notion et son SDK JavaScript » a une explication plus longue pour cela, mais essentiellement sur notre server.js
nous avons créé une route qui récupère notre base de données, et ici sur getDataFromBackend
on fait un fetch
à cette même route, qui récupérera nos données pour nous.
Remarquez comment à l’intérieur addData
Nous avons déjà const data = await getDataFromBackend();
. Cela signifie que nous sommes prêts à commencer à travailler avec nos données, et nous pouvons réellement vérifier cela ! log
cette data
variable et nous devrions voir, sur notre console, un tableau de nos entrées de base de données.
Affichage de nos données à l’écran
Maintenant que nous savons à quoi ressemblent nos données renvoyées, nous devons réfléchir à la façon dont nous voulons réellement les afficher à l’écran. Mon idée est d’avoir une carte pour chaque question, avec les différentes réponses à l’intérieur, et lorsque l’utilisateur appuie sur le bonne réponsel’arrière-plan de la réponse doit devenir vert; si c’est mauvaisil devrait tourner rouge.
Commençons par créer un <div>
pour chaque question. Nous pouvons le faire en itérant sur notre tableau avec un forEach
boucle, nous permettant de créer la <div>
et y ajouter des classes.
Alors à l’intérieur de notre addData
fonction nous pouvons faire ceci:
const addData = async () => {
const data = await getDataFromBackend();
data.forEach((value, index) => {
const div = document.createElement('div');
div.classList.add('questionContainer');
container.append(div);
});
};
Mais cela semble encore un peu vide, alors ajoutons un en-tête pour chaque carte comme ceci :
const addData = async () => {
const data = await getDataFromBackend();
data.forEach((value, index) => {
const div = document.createElement('div');
div.classList.add('questionContainer');
const numberElement = document.createElement('p');
numberElement.classList.add('numberElement');
numberElement.innerHTML = `Question ${index + 1}`;
div.appendChild(numberElement);
container.append(div);
});
};
Ici, nous créons un <p>
et lui donner une classe, et nous travaillons avec index + 1
, car les tableaux en JavaScript sont basés sur zéro et nous ne voulons pas voir la question 0, car cela n’a aucun sens ! Si nous démarrons maintenant notre application, nous devrions voir quelque chose comme ce qui est illustré ci-dessous.
La partie amusante : de nouvelles fonctions pour rendre les questions et les réponses
Maintenant pour la partie amusante ! Nous pourrions faire toute notre logique à l’intérieur addData
mais cela pourrait devenir trop confus, nous allons donc créer de nouvelles fonctions pour rendre notre question et réponses.
Commençons par le questionet travaillons un peu sur notre addData
fonction qui ne se traduira pas encore beaucoup:
const addData = async () => {
const data = await getDataFromBackend();
data.forEach((value, index) => {
const div = document.createElement('div');
div.classList.add('questionContainer');
const numberElement = document.createElement('p');
numberElement.classList.add('numberElement');
numberElement.innerHTML = `Question ${index + 1}`;
div.appendChild(numberElement);
const question = createQuestion(value.question);
div.appendChild(question);
container.append(div);
});
};
Le code que nous venons d’ajouter est très similaire à celui du numberElement
, mais ici nous attribuons une fonction à une variable et ajoutons cette variable. Remarquez aussi que nous passons value.question
dans notre createQuestion
parce que nous voulons travailler avec et rendre le question, bien sûr. Tout cela aura un sens en un rien de temps – ne vous inquiétez pas !
Maintenant, dehors et au-dessus addData
créons ce nouveau createQuestion
une fonction. À l’intérieur, nous voulons à peu près la même logique que nous avons ajoutée pour notre numberElement
: créer un élément, lui attribuer une classe et lui ajouter du contenu. Ici, nous n’utiliserons pas innerHTML
mais createTextNode
: puisque nos questions sont liées au code, si nous devions utiliser innerHTML
dans quelque chose comme <b>text</b>
cela rendrait en fait le mot text
mais avec gras au lieu de toute la syntaxe (vous pouvez voir un exemple ici). Notre finale createQuestion
ressemblera à ceci :
const createQuestion = (question) => {
const questionElement = document.createElement('h3');
questionElement.classList.add('question');
const questionNode = document.createTextNode(question);
questionElement.appendChild(questionNode);
return questionElement;
};
Si nous courons maintenant yarn start
notre navigateur devrait apparaître comme indiqué ci-dessous.
Maintenant, notre configuration pour notre réponses est à peu près le même. Faisons d’abord la même chose que nous avons fait avec createQuestion
à l’intérieur addData
:
const addData = async () => {
const data = await getDataFromBackend();
data.forEach((value, index) => {
const div = document.createElement('div');
div.classList.add('questionContainer');
const numberElement = document.createElement('p');
numberElement.classList.add('numberElement');
numberElement.innerHTML = `Question ${index + 1}`;
div.appendChild(numberElement);
const question = createQuestion(value.question);
div.appendChild(question);
const answers = createAnswers(value);
div.appendChild(answers);
container.append(div);
});
};
Et maintenant, notre recherche initiale de createAnswers
ressemblera à ceci :
const createAnswers = (value) => {
const answersDiv = document.createElement('div');
answersDiv.classList.add('answersDiv');
return answersDiv;
};
Remarquez comment nous faisons const answers = createAnswers(value);
. Nous ne pouvons pas simplement passer value.answers
à notre fonction, car nous avons aussi besoin du value.correct
. Nous pourrions au lieu de cela passer deux arguments à notre fonction : un pour le tableau de réponses et l’autre serait le Corriger une.
Rendre un tableau de réponses
Nous avons maintenant un éventail de réponses, et nous devons tous les rendre, nous avons donc besoin d’une boucle pour les parcourir tous. Le processus à l’intérieur de cette boucle sera à peu près le même que pour tous les autres éléments, nous devrions donc être avantages à ce stade du rendu des éléments sur le DOM :
const createAnswers = (value) => {
const answersDiv = document.createElement('div');
answersDiv.classList.add('answersDiv');
for (let i = 0; i < value.answers.length; i++) {
const answerElement = document.createElement('p');
answerElement.classList.add('answerOption');
const answerNode = document.createTextNode(value.answers[i].name);
answerElement.appendChild(answerNode);
answersDiv.appendChild(answerElement);
}
return answersDiv;
};
Avec ce code, nous bouclons sur notre array
en créant un élément, en lui donnant une classe et en utilisant createTextNode
pour rendre notre réponses. (Assez curieusement, si nous avions utilisé innerHTML
ici le réponses avec <script>
ne rendrait pas 😄.) Ensuite, nous ajoutons simplement ceci answerNode
à notre <p>
et en ajoutant celui-ci à notre <div>
! Si nous courons yarn start
, nous allons maintenant voir tout notre quiz ! Courtiser! 🚀
Interagir avec les réponses
Hmm… Mais nous ne pouvons pas vraiment interagir avec les réponses, et ce n’est pas vraiment un quiz si nous ne savons pas si nous avons la bonne ou la mauvaise réponse, n’est-ce pas ? On devrait régler ça !
Nous savons que nous voulons cliquer sur chaque répondre et savoir si c’est à droite ou alors mauvaisnous pouvons donc commencer par lui ajouter un écouteur d’événement comme ceci :
const createAnswers = (value) => {
const answersDiv = document.createElement('div');
answersDiv.classList.add('answersDiv');
for (let i = 0; i < value.answers.length; i++) {
const answerElement = document.createElement('p');
answerElement.classList.add('answerOption');
const answerNode = document.createTextNode(value.answers[i].name);
answerElement.addEventListener('click', () => {});
answerElement.appendChild(answerNode);
answersDiv.appendChild(answerElement);
}
return answersDiv;
};
Rappelez-vous que nous avons fait createAnswers(value)
afin que nous puissions obtenir le value.correct
? Il est maintenant temps de briller ! Lorsqu’on clique sur une réponse, il y a deux résultats possibles : l’utilisateur choisit la réponse qui est égale à la bonne réponse, ou l’utilisateur choisit une réponse qui n’est pas égale à la bonne réponse. Pour faire face à ces résultats possibles, nous allons utiliser une instruction if, et la façon dont nous allons montrer à nos utilisateurs qu’ils ont obtenu une réponse à droite ou alors mauvais passe par un changement de background-color
de la réponse. Notre logique ressemblera donc à ceci :
const createAnswers = (value) => {
const answersDiv = document.createElement('div');
answersDiv.classList.add('answersDiv');
for (let i = 0; i < value.answers.length; i++) {
const answerElement = document.createElement('p');
answerElement.classList.add('answerOption');
const answerNode = document.createTextNode(value.answers[i].name);
answerElement.addEventListener('click', () => {
answerElement.style.color = 'white';
if (value.answers[i].name !== value.correct) {
answerElement.style.backgroundColor = '#f55142';
} else {
answerElement.style.backgroundColor = '#6dbf39';
}
});
answerElement.appendChild(answerNode);
answersDiv.appendChild(answerElement);
}
return answersDiv;
};
Ainsi, à chaque clic, nous changeons la couleur du texte en blanc, puis nous vérifions si le name
propriété de chaque réponse est égale à value.correct
(ce n’est évidemment pas l’idéal, et un index serait bien mieux, mais nous avons fait de notre mieux avec les bases de données de Notion !). Si ce n’est pas le cas, nous changeons sa couleur en rouge et si c’est le cas, nous le changeons en vert !
Et voilà, notre quiz est terminé ! 🚀 N’est-ce pas fantastique ?
Récapitulatif du quiz Notion JavaScript
Dans ce tutoriel, nous avons exploré de nombreuses fonctionnalités fournies par l’API de Notion et, honnêtement, c’est toujours très excitant de voir tout ce que vous pouvez faire avec un outil aussi simple !
J’espère que cet article finira par vous inspirer à explorer l’API Notion et à créer vos propres quiz et autres trucs super avec Notion !
Si vous souhaitez tester rapidement ce projet Notion, vous pouvez le cloner depuis notre Dépôt GitHub.
Source link