Signaler un catalogue sans résultat
Objectif : Afficher un message explicite lorsque le filtre ne retourne aucune randonnée.
Un filtre peut fonctionner correctement sans trouver de randonnée. Dans ce cas, une liste vide ne doit pas laisser la page sans explication : vous devez indiquer ce qui s’est passé et aider la personne à revenir à une recherche plus large.
La page catalogue dispose déjà d’un filtre transmis par l’URL et de la fonction serveur obtenirRandonnees, comme vu dans les leçons précédentes. Ici, vous traitez le résultat de cette lecture : une collection vide est un résultat valide, différent d’une requête qui échoue.
Distinguer absence de résultat et erreur
Lorsque la lecture réussit, obtenirRandonnees renvoie un tableau. S’il ne contient aucun élément, la page peut afficher un état vide. En revanche, si la lecture rencontre une erreur réseau ou une réponse HTTP invalide, l’erreur doit continuer à remonter vers la frontière d’erreur déjà ajoutée au catalogue ; ne la convertissez pas en tableau vide.
Cette distinction évite un diagnostic trompeur. Un message comme « Aucune randonnée ne correspond à cette recherche » décrit un résultat connu ; « Impossible de charger les données » décrit une lecture qui n’a pas abouti. Gardez ces deux situations dans leurs branches respectives.
Afficher un état vide et proposer un retour
Dans app/page.tsx, conservez le chargement serveur et le formulaire de recherche existants. La condition ci-dessous doit entourer l’affichage des résultats : le message apparaît uniquement si le tableau est vide, tandis que la liste reste inchangée pour un ou plusieurs résultats.
export default async function CataloguePage({ searchParams }) {
const { difficulte } = await searchParams;
const randonnees = await obtenirRandonnees({ difficulte });
return (
<>
<h1 className="rando-titre">Randonnées à découvrir</h1>
<form className="rando-recherche" action="/">
<label htmlFor="difficulte">Difficulté</label>
<select id="difficulte" name="difficulte" defaultValue={difficulte ?? ''}>
<option value="">Toutes</option>
<option value="facile">Facile</option>
<option value="intermediaire">Intermédiaire</option>
<option value="difficile">Difficile</option>
</select>
<button className="rando-bouton" type="submit">Rechercher</button>
</form>
{randonnees.length === 0 ? (
<div className="rando-etat" role="status">
<p>Aucune randonnée ne correspond à cette recherche.</p>
{difficulte ? (
<a href="/">Afficher toutes les randonnées</a>
) : null}
</div>
) : (
<ul className="rando-liste">
{randonnees.map((randonnee) => (
<li className="rando-carte" key={randonnee.id}>
<a href={`/randonnees/${randonnee.id}`}>
<h2>{randonnee.nom}</h2>
<p>{randonnee.difficulte} · {randonnee.distance} km</p>
</a>
</li>
))}
</ul>
)}
</>
);
}Le lien « Afficher toutes les randonnées » renvoie vers /, sans paramètre de difficulté. Le formulaire conserve la même destination : vous pouvez donc également choisir « Toutes » puis relancer la recherche. Aucun état local ni code client n’est nécessaire pour cette action.
Vérifier les deux chemins d’affichage
Testez d’abord une difficulté qui renvoie des randonnées : les cartes doivent rester visibles et aucun message d’absence ne doit apparaître. Testez ensuite un filtre sans correspondance : la page doit afficher le message et le lien de retour. Enfin, provoquez une indisponibilité de la source de données dans votre environnement de test ; vous devez obtenir l’état d’erreur du catalogue, pas l’état vide.
À retenir
- Un tableau vide après une lecture réussie correspond à un état vide, pas à une erreur.
- Une erreur réseau ou HTTP doit continuer à remonter vers l’état d’erreur de la route.
- Affichez un message explicite dans un élément portant la classe rando-etat.
- Proposez un retour vers la page sans filtre lorsque la recherche est filtrée.
La prochaine leçon distinguera les états de chargement et d’erreur selon les segments de route du catalogue et des fiches détail.