LIFAP5 - TP 3/4 : Interactions serveur asynchrones

Comme dans les TP précédents, il faut télécharger et ouvrir localement les fichiers suivants, l’ensemble des fichiers est disponible dans l’archive LIFAP5-TP3-fichiers.zip.

On aura également besoin des fichiers de données suivantes disponible sur le serveur :

Ce TP 3/4 est sur deux séances, il fait suite au TP2. Le point de départ correspond à peu près au résultat attendu en fin de TP2, où on a une page d’affichage des nouvelles avec un filtre sur le mois et l’année souhaités.

L’objectif du TP 3/4 est de réorganiser le code pour pouvoir gérer un tableau de nouvelle obtenu de façon asynchrone, alors que dans le TP2 ces nouvelles étaient stockés dans un constante.

Globalement, il s’agit d’écrire un programme le plus fonctionnellement possible :


Exercice 0 : chargement de nouvelles

Cet exercice est une prise en main du code de départ.

Exercice 1 : chargement dynamique des nouvelles : prise en main

Au lieu d’utiliser une liste de nouvelles statique, fournie directement dans le code JavaScript par la constante globale donnees_exemple, on va vouloir charger dynamiquement les nouvelles depuis un fichier téléchargé par le navigateur.

La fonction fournie charge_donnees(url, callback) charge, de façon asynchrone, le fichier json à l’adresse url, puis appelle la fonction callback en lui passant en argument le contenu du fichier chargé. Cette fonction utilise l’API fetch vue en cours et pourra servir d’exemple pour les exercices suivants. Vous pouvez aussi vous servir directement de fetch en utilisant les promesses, sans passer par charge_donnees.

A ce stade, le téléchargement doit fonctionner mais l’affichage des nouvelles filtrées n’est pas encore correct. Ne passez pas à la suite si vous ne comprenez pas pourquoi.

Exercice 2 : Passage d’information via des fermetures : se passer de donnees_exemple

À la fin de cet exercice, l’affichage des nouvelles doit être fonctionnel et utiliser les bonnes données chargées dynamiquement sans utiliser de variables globales.

Attention à la gestion des événements: il faut bien réfléchir à ce que l’on range dans les champs onchange des menus : on y place une fonction qui n’attend pas d’arguments et qui sera empilée dans la task queue du navigateur. Comme cette fonction doit accéder aux nouvelles courantes, il faut utiliser une fermeture qui va capturer ces nouvelles.

Exercice 3 : Affichage du contenu des nouvelles

Pour le moment, on affiche juste la liste des titres des nouvelles. On souhaite en afficher aussi le contenu, mais seulement lorsque l’on clique sur le titre de la nouvelle. On souhaite également que l’affichage d’un contenu masque les autres contenus. Pour cela on propose de procéder de la manière suivante:

Il est attendu d’arriver à cet exercice en fin de la première séance de TP. Si ce n’est pas le cas, le faire entre les deux séances.

Aide


Exercice 4 : l’annuaire de nouvelles

On ne peut pas faire cet exercice sans avoir terminé le précédent, vu qu’il s’agit d’une extension.

Le fichier annuaire.json contient une structure JSON avec des liens vers des listes de nouvelles.

Afin d’afficher un message d’erreur à l’utilisateur en cas de problème de chargement, on utilisera directement l’API fetch vue en cours au lieu de la fonction charge_donnees.

Exercice 5 : soumission de données en POST

Jusqu’à présent, les requêtes fetch n’ont été utilisées que pour lire des données sur le serveur, dans cet exercice on va en envoyer. Pour cela, on va utiliser un formulaire simple comme le suivant. Le but sera d’envoyer le contenu saisi au serveur (qu’on imagine ajouter l’utilisateur à une base de données) et de récupérer son résultat.

<form action="#" method="get" class="form-example">
  <div class="form-example">
    <label for="name">Nom : </label>
    <input type="text" name="name" id="name" required />
  </div>
  <div class="form-example">
    <label for="email">Email : </label>
    <input type="email" name="email" id="email" />
  </div>

  <div class="form-example">
    <label for="hard">Hard rock</label>
    <input type="radio" name="category" value="hard" id="hard" />
  </div>
  <div class="form-example">
    <label for="heavy">Heavy metal</label>
    <input type="radio" name="category" value="heavy" id="heavy" />
  </div>
  <div class="form-example">
    <label for="speed">Speed metal</label>
    <input type="radio" name="category" value="speed" id="speed" />
  </div>
  <div class="form-example">
    <label for="thrash">Thrash metal</label>
    <input type="radio" name="category" value="thrash" id="thrash" />
  </div>

  <div class="form-example">
    <input type="submit" value="Envoyer" />
  </div>
</form>

On veut maintenant récupérer les contenus saisis par l’utilisateur. Soit on parcourt le DOM pour regarder la propriété value des (contreparties DOM des) éléments input qui composent le formulaire, soit on passe par un objet FormData. C’est la seconde solution qu’on retiend ici pour votre handler.

fetch('https://lifap5.univ-lyon1.fr/echo', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify(data),
});