La notion est un application multi-fonctions pour organiser toutes sortes de contenus, des notes aux calendriers et rappels. Dans notre dernier article, “Premiers pas avec l’API Notion et son SDK JavaScript”, nous nous sommes penchés sur la façon d’utiliser 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 front-end et back-end, 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é de 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 que d’une copie récente de Noeud installé sur votre machine. Comme toujours, le le code final du tutoriel peut être trouvé 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 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 trouver 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 en bas du chemin à quoi ressemblent les données récupérées à partir de cela). 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. appuie sur le Mes intégrations bouton en haut à droite puis cliquez sur Créer une nouvelle intégration. Nous devons renseigner notre titre et veiller à bien 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 pour l’endroit où nous voulons utiliser notre intégration. Nous n’avons rien à faire sur cette page à part copier notre jeton et appuyer sur Sauvegarder les modifications.
Revenons maintenant à notre espace de travail Notion. Dans notre base de données Notion nouvellement créée, nous voulons appuyer sur Partager, alors Inviter. Nous pourrons alors choisir notre intégration nouvellement créée. Si nous le choisissons et appuyons sur Inviter, notre configuration Notion est terminée. Bien fait! ??
La configuration du code
Pour la configuration de notre code, nous utiliserons un référentiel de modèles Notion (que nous pouvons 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 forker 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 rentrons dans beaucoup de détails pour chaque bit de code (le repo a aussi 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 npm install
sur notre terminal à l’intérieur du dossier. Dans ce projet, nous avons trois dépendances : le @notionhq/client, dotenv et Express. Nous utiliserons dotenv pour gérer nos variables et les garder en sécurité (comme celui que nous avons vu sur notre intégration) et Express pour créer notre back-end et serveur pour notre application.
Pour gérer nos variables avec dotenv, créez un .env
à 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égrations, et notre NOTION_API_DATABASE
peut être trouvé en allant sur 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 et contient 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 à l’intérieur de notre référentiel, notez que sur notre .gitignore
nous avons le .env
y déposer ; les .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 référentiel 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 connectés avec succès à notre base de données Notion, nous allons donc naviguer vers notre .index.js
fichier et enregistrez 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 nos données requises. Notre getDatabase
la fonction ressemblera à ceci :
exportsgetDatabase = async function () {
const response = await notiondatabasesquery({ database_id: databaseId });
const responseResults = responseresultsmap((page) => {
return {
id: pageid,
question: pagepropertiesQuestiontitle[0]plain_text,
answers: pagepropertiesAnswersmulti_select,
correct: pagepropertiesCorrectrich_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, lorsque vous développez et travaillez avec votre propre base de données, vous devez continuellement rechercher 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 passons à peu près un appel à notre API et choisissons 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 nous occuper de notre HTML et CSS, car ils sont assez directs ! Nous n’apporterons aucune modification à notre code HTML à partir du modèle, et à 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 allons 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
fonction. Si cela vous embrouille, “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éé un itinéraire qui récupère notre base de données, et ici sur getDataFromBackend
nous faisons un fetch
à ce même itinéraire, 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 le vérifier ! 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 manière dont nous voulons réellement les afficher à l’écran. Mon idée pour cela 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éponse, l’arrière-plan de la réponse devrait tourner vert; si c’est tort, ça doit 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 ajoutez-y des classes.
Alors à l’intérieur de notre addData
fonction, nous pouvons faire ceci:
const addData = async () => {
const data = await getDataFromBackend();
dataforEach((value, index) => {
const div = documentcreateElement('div');
divclassListadd('questionContainer');
containerappend(div);
});
};
Mais cela semble toujours un peu vide, alors ajoutons un en-tête pour chaque carte comme ceci :
const addData = async () => {
const data = await getDataFromBackend();
dataforEach((value, index) => {
const div = documentcreateElement('div');
divclassListadd('questionContainer');
const numberElement = documentcreateElement('p');
numberElementclassListadd('numberElement');
numberElementinnerHTML = `Question ${index + 1}`;
divappendChild(numberElement);
containerappend(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 pas de 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 réponses
Maintenant pour la partie amusante ! Nous pourrions faire toute notre logique à l’intérieur addData
, mais cela pourrait devenir trop compliqué, nous allons donc créer de nouvelles fonctions pour rendre notre question et réponses.
Commençons par le question, et travaillons sur notre addData
fonction qui ne se traduira toujours pas par grand-chose :
const addData = async () => {
const data = await getDataFromBackend();
dataforEach((value, index) => {
const div = documentcreateElement('div');
divclassListadd('questionContainer');
const numberElement = documentcreateElement('p');
numberElementclassListadd('numberElement');
numberElementinnerHTML = `Question ${index + 1}`;
divappendChild(numberElement);
const question = createQuestion(valuequestion);
divappendChild(question);
containerappend(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 prendra un sens en un rien de temps – ne vous inquiétez pas !
Maintenant, à l’extérieur et au-dessus addData
, créons ce nouveau createQuestion
fonction. À l’intérieur, nous voulons à peu près la même logique que nous avons ajoutée pour notre numberElement
: créez un élément, donnez-lui une classe et ajoutez-y du contenu. Ici, nous utiliserons non 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 = documentcreateElement('h3');
questionElementclassListadd('question');
const questionNode = documentcreateTextNode(question);
questionElementappendChild(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();
dataforEach((value, index) => {
const div = documentcreateElement('div');
divclassListadd('questionContainer');
const numberElement = documentcreateElement('p');
numberElementclassListadd('numberElement');
numberElementinnerHTML = `Question ${index + 1}`;
divappendChild(numberElement);
const question = createQuestion(valuequestion);
divappendChild(question);
const answers = createAnswers(value);
divappendChild(answers);
containerappend(div);
});
};
Et maintenant notre recherche initiale pour createAnswers
ressemblera à ceci :
const createAnswers = (value) => {
const answersDiv = documentcreateElement('div');
answersDivclassListadd('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 de value.correct
. Au lieu de cela, nous pourrions passer deux arguments à notre fonction : un pour le tableau de réponses et l’autre serait le correct une.
Rendre un tableau de réponses
Nous avons maintenant une gamme 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 = documentcreateElement('div');
answersDivclassListadd('answersDiv');
for (let i = 0; i < valueanswerslength; i++) {
const answerElement = documentcreateElement('p');
answerElementclassListadd('answerOption');
const answerNode = documentcreateTextNode(valueanswers[i]name);
answerElementappendChild(answerNode);
answersDivappendChild(answerElement);
}
return answersDiv;
};
Avec ce code, nous parcourons notre array
, créer un élément, lui donner une classe et utiliser createTextNode
rendre notre réponses. (Assez curieusement, si nous avions utilisé innerHTML
ici le réponses avec <script>
ne rendrait pas answerNode
à notre <p>
et en ajoutant celui-ci à notre <div>
! Si nous courons yarn start
, nous allons maintenant voir l’intégralité de 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 arranger ça !
Nous savons que nous voulons cliquer sur chacun réponse et savoir si c’est droit ou tort, nous pouvons donc commencer par lui ajouter un écouteur d’événement comme ceci :
const createAnswers = (value) => {
const answersDiv = documentcreateElement('div');
answersDivclassListadd('answersDiv');
for (let i = 0; i < valueanswerslength; i++) {
const answerElement = documentcreateElement('p');
answerElementclassListadd('answerOption');
const answerNode = documentcreateTextNode(valueanswers[i]name);
answerElementaddEventListener('click', () => {});
answerElementappendChild(answerNode);
answersDivappendChild(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 ! Lorsque nous cliquons 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 droit ou tort est par un changement de background-color
de la réponse. Notre logique ressemblera donc à ceci :
const createAnswers = (value) => {
const answersDiv = documentcreateElement('div');
answersDivclassListadd('answersDiv');
for (let i = 0; i < valueanswerslength; i++) {
const answerElement = documentcreateElement('p');
answerElementclassListadd('answerOption');
const answerNode = documentcreateTextNode(valueanswers[i]name);
answerElementaddEventListener('click', () => {
answerElementstylecolor = 'white';
if (valueanswers[i]name !== valuecorrect) {
answerElementstylebackgroundColor = '#f55142';
} else {
answerElementstylebackgroundColor = '#6dbf39';
}
});
answerElementappendChild(answerNode);
answersDivappendChild(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, on change sa couleur en rouge et si c’est le cas, on la change en vert !
Et voilà notre quiz terminé !
Conclusion du quiz JavaScript de Notion
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.
— to www.sitepoint.com