Adloun

Vue : construire une application web (école d'ingénieur) · Chapitre 12 · Exercice de TD

La recherche au serveur

Projet : la Librairie en application Vue · niveau 3 (difficile)

Énoncé

Avec un très grand catalogue, la recherche doit être faite par le serveur (GET /api/livres?q=…). Écrire un composant de recherche qui interroge le serveur, sans envoyer une requête à chaque touche : seulement quand l'utilisateur a cessé de taper depuis 300 ms. Combien de requêtes partent quand on tape « java » à raison d'une touche toutes les 100 ms ? Le vérifier avec un test à temps simulé.

Corrigé

On combine le composable useDifferee du chapitre 11 et useFetch, dont l'adresse est une fonction de la recherche différée :


<script setup>
import { ref } from "vue";
import { useFetch } from "@/composables/useFetch.js";
import { useDifferee } from "./useDifferee.js";

const saisie = ref("");
// Le serveur ne reçoit la recherche qu'après 300 ms sans frappe.
const recherche = useDifferee(saisie, 300);
const { donnees: livres, chargement } = useFetch(
  () => `/api/livres?q=${encodeURIComponent(recherche.value)}`,
);
</script>

<template>
  <p>
    <label for="q">Rechercher</label>
    <input
      id="q"
      v-model="saisie"
      type="search"
    >
  </p>
  <ul :aria-busy="chargement">
    <li
      v-for="livre in livres ?? []"
      :key="livre.isbn"
    >
      {{ livre.titre }}
    </li>
  </ul>
</template>

test("quatre frappes rapides, une seule requête de recherche", async () => {
  vi.useFakeTimers();
  const fetch = vi.fn(async () => ({ ok: true, status: 200, json: async () => [] }));
  vi.stubGlobal("fetch", fetch);
  const page = mount(RechercheServeur);
  for (const texte of ["j", "ja", "jav", "java"]) {
    await page.find("#q").setValue(texte);
    vi.advanceTimersByTime(100); // 100 ms entre deux touches
  }
  vi.advanceTimersByTime(300); // l'utilisateur s'arrête
  await flushPromises();
  console.info(fetch.mock.calls.map(([url]) => url));
  expect(fetch).toHaveBeenCalledTimes(2);
});

[ '/api/livres?q=', '/api/livres?q=java' ]

Deux requêtes : celle du premier affichage (recherche vide), puis une seule pour « java », 300 ms après la dernière touche. Les trois états intermédiaires (« j », « ja », « jav ») n'ont jamais quitté le navigateur. Si une ancienne requête revenait après une plus récente, useFetch l'aurait de toute façon annulée.

100 % gratuit

La suite du chapitre est sur Adloun

Exercice suivant et tuteur

Sans compte : le cours et le premier QCM. Exercices et tuteur : inscription gratuite en 30 secondes, sans carte bancaire.

Le cours du chapitre · Tous les exercices du chapitre

Exercice suivant et tuteur →