Leçon 12 / 15

Ajouter des filtres aux listes

20 min Node.js — API Express et code asynchrone Gratuit

Objectif : Filtrer les commandes par statut et les produits par catégorie à partir de paramètres de requête.

Une liste trop large est difficile à exploiter : un client doit pouvoir demander les commandes en attente ou les produits d’une catégorie précise. Vous allez lire ces critères dans la requête, puis les appliquer dans le service sans modifier les routes ni dupliquer la sélection dans le contrôleur.

Les paramètres de requête sont déjà connus : la leçon « Lire les requêtes et formater les réponses » a montré comment les lire avec req.query. Ici, vous allez utiliser statut pour les commandes et categorie pour les produits. Une requête sans critère doit continuer à renvoyer toute la liste.

Faire porter le filtrage par le service

Le contrôleur reçoit les critères HTTP et les transmet au service. Le service connaît la structure des données et décide quelles entrées conserver. Cette répartition vous permet de changer la source des données sans déplacer la logique de filtrage dans la route.

Pour isoler la logique de sélection, le programme autonome suivant reçoit une liste et un objet de critères. Il n’accède ni à Express ni au stockage : vous pouvez l’exécuter avec Node.js pour vérifier le comportement avant de raccorder les mêmes règles à vos services. Les deux critères sont indépendants et peuvent être combinés.

Exemple autonome : commandes et produits filtrésJavaScript
const commandes = [
  { id: 1, statut: 'en-attente', produitId: 2 },
  { id: 2, statut: 'expediee', produitId: 1 },
  { id: 3, statut: 'en-attente', produitId: 1 }
];

const produits = [
  { id: 1, nom: 'Clavier', categorie: 'informatique' },
  { id: 2, nom: 'Tasse', categorie: 'maison' },
  { id: 3, nom: 'Souris', categorie: 'informatique' }
];

function filtrerCommandes(liste, filtres = {}) {
  return liste.filter((commande) => {
    return !filtres.statut || commande.statut === filtres.statut;
  });
}

function filtrerProduits(liste, filtres = {}) {
  return liste.filter((produit) => {
    return !filtres.categorie || produit.categorie === filtres.categorie;
  });
}

console.log(filtrerCommandes(commandes, { statut: 'en-attente' }));
console.log(filtrerProduits(produits, { categorie: 'informatique' }));
console.log(filtrerCommandes(commandes, {}));
Aperçu du rendu
Chargement de l'aperçu…
Résultat attendu
[
  { id: 1, statut: 'en-attente', produitId: 2 },
  { id: 3, statut: 'en-attente', produitId: 1 }
]
[
  { id: 1, nom: 'Clavier', categorie: 'informatique' },
  { id: 3, nom: 'Souris', categorie: 'informatique' }
]
[
  { id: 1, statut: 'en-attente', produitId: 2 },
  { id: 2, statut: 'expediee', produitId: 1 },
  { id: 3, statut: 'en-attente', produitId: 1 }
]

La condition !filtres.statut laisse passer chaque commande lorsque le critère est absent ou vide. Lorsqu’il est fourni, seule une égalité exacte est retenue ; le service des produits suit le même principe pour la catégorie. Comme chaque ressource possède son propre service, chaque fonction examine uniquement les champs qui lui appartiennent.

Transmettre les critères depuis la requête

Dans le projet, le contrôleur de commandes doit transmettre au service la valeur de req.query.statut ; celui des produits transmet req.query.categorie. Le service reçoit alors un objet de filtres, par exemple { statut: req.query.statut }, puis applique le critère à sa liste existante. Gardez les fonctions de lecture asynchrones si elles le sont déjà : elles peuvent filtrer le résultat obtenu sans changer la forme de la réponse HTTP.

Combiner les filtres de commandes

Les commandes peuvent être filtrées à la fois par statut et par produit. Construisez une seule condition qui accepte chaque critère lorsqu’il est absent et exige une correspondance lorsqu’il est présent. La combinaison des conditions avec && renvoie uniquement les commandes qui satisfont tous les critères fournis.

Deux critères indépendants dans un service de commandesJavaScript
function filtrerCommandes(liste, filtres = {}) {
  return liste.filter((commande) => {
    const statutCorrespond = !filtres.statut
      || commande.statut === filtres.statut;
    const produitCorrespond = !filtres.produitId
      || commande.produitId === Number(filtres.produitId);

    return statutCorrespond && produitCorrespond;
  });
}

const resultats = filtrerCommandes(commandes, {
  statut: 'en-attente',
  produitId: '1'
});

console.log(resultats);
Aperçu du rendu
Chargement de l'aperçu…
Résultat attendu
[ { id: 3, statut: 'en-attente', produitId: 1 } ]

Dans cet exemple, produitId arrive sous forme de texte depuis la chaîne de requête. La conversion avec Number permet de comparer cette valeur à un identifiant numérique stocké dans les commandes. Vous obtenez une liste vide si aucun élément ne correspond ; ce résultat reste une liste valide, et non une erreur de ressource absente.

À retenir

  • Lisez les critères dans req.query, puis transmettez-les du contrôleur au service.
  • Filtrez les commandes par statut et les produits par catégorie dans leurs services respectifs.
  • Un critère absent doit laisser la liste inchangée.
  • Combinez les critères indépendants pour ne conserver que les résultats correspondants.
  • Ne modifiez pas la liste source lorsque vous produisez une liste filtrée.

Dans la prochaine leçon, vous préparerez des données cohérentes entre les commandes et les produits pour éprouver ces filtres.

Envie d'aller plus loin ?

Les cours Enovatic sont gratuits et le resteront. Si vous cherchez un accompagnement encadré, nos formations professionnelles sont animées par les mêmes formateurs.