You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Web-Dev-For-Beginners/translations/fr/7-bank-project/3-data
leestott 7cfaffabb5
🌐 Update translations via Co-op Translator
3 weeks ago
..
README.md 🌐 Update translations via Co-op Translator 3 weeks ago
assignment.md 🌐 Update translations via Co-op Translator 4 weeks ago

README.md

Créer une application bancaire Partie 3 : Méthodes pour récupérer et utiliser des données

Quiz pré-lecture

Quiz pré-lecture

Introduction

Au cœur de chaque application web se trouvent les données. Les données peuvent prendre de nombreuses formes, mais leur objectif principal est toujours d'afficher des informations à l'utilisateur. Avec des applications web devenant de plus en plus interactives et complexes, la manière dont l'utilisateur accède et interagit avec ces informations est désormais un aspect clé du développement web.

Dans cette leçon, nous verrons comment récupérer des données d'un serveur de manière asynchrone et utiliser ces données pour afficher des informations sur une page web sans recharger le HTML.

Prérequis

Vous devez avoir construit la partie Formulaire de connexion et d'inscription de l'application web pour cette leçon. Vous devez également installer Node.js et exécuter l'API serveur localement pour obtenir les données de compte.

Vous pouvez vérifier que le serveur fonctionne correctement en exécutant cette commande dans un terminal :

curl http://localhost:5000/api
# -> should return "Bank API v1.0.0" as a result

AJAX et récupération de données

Les sites web traditionnels mettent à jour le contenu affiché lorsque l'utilisateur sélectionne un lien ou soumet des données via un formulaire, en rechargeant la page HTML complète. Chaque fois que de nouvelles données doivent être chargées, le serveur web renvoie une toute nouvelle page HTML qui doit être traitée par le navigateur, interrompant l'action en cours de l'utilisateur et limitant les interactions pendant le rechargement. Ce flux de travail est également appelé Application Multi-Page ou MPA.

Flux de mise à jour dans une application multi-page

Lorsque les applications web ont commencé à devenir plus complexes et interactives, une nouvelle technique appelée AJAX (Asynchronous JavaScript and XML) a émergé. Cette technique permet aux applications web d'envoyer et de récupérer des données d'un serveur de manière asynchrone en utilisant JavaScript, sans avoir à recharger la page HTML, ce qui entraîne des mises à jour plus rapides et des interactions utilisateur plus fluides. Lorsque de nouvelles données sont reçues du serveur, la page HTML actuelle peut également être mise à jour avec JavaScript en utilisant l'API DOM. Avec le temps, cette approche a évolué pour devenir ce que l'on appelle aujourd'hui une Application Mono-Page ou SPA.

Flux de mise à jour dans une application mono-page

Lorsque AJAX a été introduit pour la première fois, la seule API disponible pour récupérer des données de manière asynchrone était XMLHttpRequest. Mais les navigateurs modernes implémentent désormais l'API Fetch, plus pratique et puissante, qui utilise des promesses et est mieux adaptée pour manipuler des données JSON.

Bien que tous les navigateurs modernes prennent en charge l'API Fetch, si vous souhaitez que votre application web fonctionne sur des navigateurs anciens ou obsolètes, il est toujours conseillé de vérifier d'abord le tableau de compatibilité sur caniuse.com.

Tâche

Dans la leçon précédente, nous avons implémenté le formulaire d'inscription pour créer un compte. Nous allons maintenant ajouter du code pour se connecter avec un compte existant et récupérer ses données. Ouvrez le fichier app.js et ajoutez une nouvelle fonction login :

async function login() {
  const loginForm = document.getElementById('loginForm')
  const user = loginForm.user.value;
}

Ici, nous commençons par récupérer l'élément formulaire avec getElementById(), puis nous obtenons le nom d'utilisateur à partir de l'entrée avec loginForm.user.value. Chaque contrôle de formulaire peut être accédé par son nom (défini dans le HTML avec l'attribut name) en tant que propriété du formulaire.

De manière similaire à ce que nous avons fait pour l'inscription, nous allons créer une autre fonction pour effectuer une requête au serveur, mais cette fois pour récupérer les données du compte :

async function getAccount(user) {
  try {
    const response = await fetch('//localhost:5000/api/accounts/' + encodeURIComponent(user));
    return await response.json();
  } catch (error) {
    return { error: error.message || 'Unknown error' };
  }
}

Nous utilisons l'API fetch pour demander les données de manière asynchrone au serveur, mais cette fois, nous n'avons pas besoin de paramètres supplémentaires autres que l'URL à appeler, car nous ne faisons que demander des données. Par défaut, fetch crée une requête HTTP GET, ce qui est exactement ce que nous recherchons ici.

encodeURIComponent() est une fonction qui échappe les caractères spéciaux pour les URL. Quels problèmes pourrions-nous rencontrer si nous n'appelons pas cette fonction et utilisons directement la valeur user dans l'URL ?

Mettons maintenant à jour notre fonction login pour utiliser getAccount :

async function login() {
  const loginForm = document.getElementById('loginForm')
  const user = loginForm.user.value;
  const data = await getAccount(user);

  if (data.error) {
    return console.log('loginError', data.error);
  }

  account = data;
  navigate('/dashboard');
}

Tout d'abord, comme getAccount est une fonction asynchrone, nous devons utiliser le mot-clé await pour attendre le résultat du serveur. Comme pour toute requête serveur, nous devons également gérer les cas d'erreur. Pour l'instant, nous ajouterons simplement un message de journal pour afficher l'erreur, et nous y reviendrons plus tard.

Ensuite, nous devons stocker les données quelque part pour pouvoir les utiliser plus tard pour afficher les informations du tableau de bord. Comme la variable account n'existe pas encore, nous allons créer une variable globale pour cela en haut de notre fichier :

let account = null;

Une fois les données utilisateur enregistrées dans une variable, nous pouvons naviguer de la page login à la page dashboard en utilisant la fonction navigate() que nous avons déjà.

Enfin, nous devons appeler notre fonction login lorsque le formulaire de connexion est soumis, en modifiant le HTML :

<form id="loginForm" action="javascript:login()">

Testez que tout fonctionne correctement en enregistrant un nouveau compte et en essayant de vous connecter avec ce même compte.

Avant de passer à la partie suivante, nous pouvons également compléter la fonction register en ajoutant ceci à la fin de la fonction :

account = result;
navigate('/dashboard');

Saviez-vous que par défaut, vous ne pouvez appeler les API serveur que depuis le même domaine et port que la page web que vous consultez ? C'est un mécanisme de sécurité appliqué par les navigateurs. Mais attendez, notre application web fonctionne sur localhost:3000 alors que l'API serveur fonctionne sur localhost:5000, pourquoi cela fonctionne-t-il ? En utilisant une technique appelée Cross-Origin Resource Sharing (CORS), il est possible d'effectuer des requêtes HTTP inter-origines si le serveur ajoute des en-têtes spéciaux à la réponse, permettant des exceptions pour des domaines spécifiques.

Apprenez-en davantage sur les API en suivant cette leçon

Mettre à jour le HTML pour afficher les données

Maintenant que nous avons les données utilisateur, nous devons mettre à jour le HTML existant pour les afficher. Nous savons déjà comment récupérer un élément du DOM en utilisant par exemple document.getElementById(). Une fois que vous avez un élément de base, voici quelques API que vous pouvez utiliser pour le modifier ou lui ajouter des éléments enfants :

  • En utilisant la propriété textContent, vous pouvez changer le texte d'un élément. Notez que changer cette valeur supprime tous les enfants de l'élément (s'il y en a) et les remplace par le texte fourni. Ainsi, c'est également une méthode efficace pour supprimer tous les enfants d'un élément donné en lui assignant une chaîne vide ''.

  • En utilisant document.createElement() avec la méthode append(), vous pouvez créer et attacher un ou plusieurs nouveaux éléments enfants.

En utilisant la propriété innerHTML d'un élément, il est également possible de modifier son contenu HTML, mais cela doit être évité car c'est vulnérable aux attaques de cross-site scripting (XSS).

Tâche

Avant de passer à l'écran du tableau de bord, il y a une chose de plus que nous devrions faire sur la page login. Actuellement, si vous essayez de vous connecter avec un nom d'utilisateur qui n'existe pas, un message est affiché dans la console, mais pour un utilisateur normal, rien ne change et vous ne savez pas ce qui se passe.

Ajoutons un élément de type placeholder dans le formulaire de connexion où nous pourrons afficher un message d'erreur si nécessaire. Un bon endroit serait juste avant le bouton <button> de connexion :

...
<div id="loginError"></div>
<button>Login</button>
...

Cet élément <div> est vide, ce qui signifie que rien ne sera affiché à l'écran tant que nous n'y ajouterons pas de contenu. Nous lui donnons également un id pour pouvoir le récupérer facilement avec JavaScript.

Retournez dans le fichier app.js et créez une nouvelle fonction utilitaire updateElement :

function updateElement(id, text) {
  const element = document.getElementById(id);
  element.textContent = text;
}

Celle-ci est assez simple : étant donné un id d'élément et un texte, elle mettra à jour le contenu texte de l'élément DOM correspondant à cet id. Utilisons cette méthode à la place du précédent message d'erreur dans la fonction login :

if (data.error) {
  return updateElement('loginError', data.error);
}

Maintenant, si vous essayez de vous connecter avec un compte invalide, vous devriez voir quelque chose comme ceci :

Capture d'écran montrant le message d'erreur affiché lors de la connexion

Nous avons maintenant un texte d'erreur qui s'affiche visuellement, mais si vous essayez avec un lecteur d'écran, vous remarquerez que rien n'est annoncé. Pour que le texte ajouté dynamiquement à une page soit annoncé par les lecteurs d'écran, il devra utiliser quelque chose appelé une Région Active (Live Region). Ici, nous allons utiliser un type spécifique de région active appelé une alerte :

<div id="loginError" role="alert"></div>

Implémentez le même comportement pour les erreurs de la fonction register (n'oubliez pas de mettre à jour le HTML).

Afficher les informations sur le tableau de bord

En utilisant les mêmes techniques que nous venons de voir, nous allons également nous occuper d'afficher les informations du compte sur la page du tableau de bord.

Voici à quoi ressemble un objet compte reçu du serveur :

{
  "user": "test",
  "currency": "$",
  "description": "Test account",
  "balance": 75,
  "transactions": [
    { "id": "1", "date": "2020-10-01", "object": "Pocket money", "amount": 50 },
    { "id": "2", "date": "2020-10-03", "object": "Book", "amount": -10 },
    { "id": "3", "date": "2020-10-04", "object": "Sandwich", "amount": -5 }
  ],
}

Remarque : pour vous faciliter la tâche, vous pouvez utiliser le compte test préexistant qui est déjà rempli avec des données.

Tâche

Commençons par remplacer la section "Balance" dans le HTML pour ajouter des éléments de type placeholder :

<section>
  Balance: <span id="balance"></span><span id="currency"></span>
</section>

Nous ajouterons également une nouvelle section juste en dessous pour afficher la description du compte :

<h2 id="description"></h2>

Comme la description du compte fonctionne comme un titre pour le contenu en dessous, elle est balisée sémantiquement comme un titre. Apprenez-en davantage sur l'importance de la structure des titres pour l'accessibilité, et examinez attentivement la page pour déterminer ce qui pourrait également être un titre.

Ensuite, nous allons créer une nouvelle fonction dans app.js pour remplir le placeholder :

function updateDashboard() {
  if (!account) {
    return navigate('/login');
  }

  updateElement('description', account.description);
  updateElement('balance', account.balance.toFixed(2));
  updateElement('currency', account.currency);
}

Tout d'abord, nous vérifions que nous avons les données du compte nécessaires avant d'aller plus loin. Ensuite, nous utilisons la fonction updateElement() que nous avons créée plus tôt pour mettre à jour le HTML.

Pour rendre l'affichage du solde plus joli, nous utilisons la méthode toFixed(2) pour forcer l'affichage de la valeur avec 2 chiffres après la virgule.

Nous devons maintenant appeler notre fonction updateDashboard() chaque fois que la page du tableau de bord est chargée. Si vous avez déjà terminé l'exercice de la leçon 1, cela devrait être simple, sinon vous pouvez utiliser l'implémentation suivante.

Ajoutez ce code à la fin de la fonction updateRoute() :

if (typeof route.init === 'function') {
  route.init();
}

Et mettez à jour la définition des routes avec :

const routes = {
  '/login': { templateId: 'login' },
  '/dashboard': { templateId: 'dashboard', init: updateDashboard }
};

Avec ce changement, chaque fois que la page du tableau de bord est affichée, la fonction updateDashboard() est appelée. Après une connexion, vous devriez alors pouvoir voir le solde du compte, la devise et la description.

Créer dynamiquement des lignes de tableau avec des modèles HTML

Dans la première leçon, nous avons utilisé des modèles HTML avec la méthode appendChild() pour implémenter la navigation dans notre application. Les modèles peuvent également être plus petits et utilisés pour remplir dynamiquement des parties répétitives d'une page.

Nous allons utiliser une approche similaire pour afficher la liste des transactions dans le tableau HTML.

Tâche

Ajoutez un nouveau modèle dans le <body> du HTML :

<template id="transaction">
  <tr>
    <td></td>
    <td></td>
    <td></td>
  </tr>
</template>

Ce modèle représente une seule ligne de tableau, avec les 3 colonnes que nous voulons remplir : date, objet et montant d'une transaction.

Ensuite, ajoutez cette propriété id à l'élément <tbody> du tableau dans le modèle du tableau de bord pour le rendre plus facile à trouver avec JavaScript :

<tbody id="transactions"></tbody>

Notre HTML est prêt, passons au code JavaScript et créons une nouvelle fonction createTransactionRow :

function createTransactionRow(transaction) {
  const template = document.getElementById('transaction');
  const transactionRow = template.content.cloneNode(true);
  const tr = transactionRow.querySelector('tr');
  tr.children[0].textContent = transaction.date;
  tr.children[1].textContent = transaction.object;
  tr.children[2].textContent = transaction.amount.toFixed(2);
  return transactionRow;
}

Cette fonction fait exactement ce que son nom implique : en utilisant le modèle que nous avons créé plus tôt, elle crée une nouvelle ligne de tableau et remplit son contenu avec les données de la transaction. Nous utiliserons cela dans notre fonction updateDashboard() pour remplir le tableau :

const transactionsRows = document.createDocumentFragment();
for (const transaction of account.transactions) {
  const transactionRow = createTransactionRow(transaction);
  transactionsRows.appendChild(transactionRow);
}
updateElement('transactions', transactionsRows);

Ici, nous utilisons la méthode document.createDocumentFragment() qui crée un nouveau fragment DOM sur lequel nous pouvons travailler, avant de l'attacher finalement à notre tableau HTML.

Il reste encore une chose à faire avant que ce code puisse fonctionner, car notre fonction updateElement() prend actuellement en charge uniquement le contenu texte. Modifions un peu son code :

function updateElement(id, textOrNode) {
  const element = document.getElementById(id);
  element.textContent = ''; // Removes all children
  element.append(textOrNode);
}

Nous utilisons la méthode append() car elle permet d'attacher soit du texte, soit des nœuds DOM à un élément parent, ce qui est parfait pour tous nos cas d'utilisation. Si vous essayez de vous connecter avec le compte test, vous devriez maintenant voir une liste de transactions sur le tableau de bord 🎉.


🚀 Défi

Travaillez ensemble pour faire en sorte que la page du tableau de bord ressemble à une véritable application bancaire. Si vous avez déjà stylisé votre application, essayez d'utiliser des media queries pour créer un design responsive qui fonctionne bien à la fois sur les appareils de bureau et mobiles.

Voici un exemple de page de tableau de bord stylisée :

Capture d'écran d'un exemple de résultat du tableau de bord après stylisation

Quiz après le cours

Quiz après le cours

Devoir

Refactorisez et commentez votre code


Avertissement :
Ce document a été traduit à l'aide du service de traduction automatique Co-op Translator. Bien que nous nous efforcions d'assurer l'exactitude, veuillez noter que les traductions automatisées peuvent contenir des erreurs ou des inexactitudes. Le document original dans sa langue d'origine doit être considéré comme la source faisant autorité. Pour des informations critiques, il est recommandé de faire appel à une traduction humaine professionnelle. Nous déclinons toute responsabilité en cas de malentendus ou d'interprétations erronées résultant de l'utilisation de cette traduction.