Magazine Gadgets

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

Publié le 26 octobre 2021 par Mycamer

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.

Notre tableau de notions rempli avec nos questions, réponses et choix corrects

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.

Ce que la journalisation de la requête de réponse récupère

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.

Enregistrement de nos 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.

Nous affichons maintenant une carte pour chaque question et affichons un en-tête qui indique Question ${index + 1}

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.

Nous devrions maintenant voir la carte de question avec l'en-tête de la question et la question nouvellement ajoutée

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

😄
.) Ensuite, nous ajoutons simplement ceci 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! ??

Une vue partielle de notre quiz avec tous les éléments requis dedans

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 !

Notre quiz est maintenant complet avec une interaction complète pour les bonnes et les mauvaises réponses

Et voilà notre quiz terminé !

🚀
N’est-ce pas fantastique ?

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


Retour à La Une de Logo Paperblog

A propos de l’auteur


Mycamer Voir son profil
Voir son blog

l'auteur n'a pas encore renseigné son compte l'auteur n'a pas encore renseigné son compte

Magazines