Bonjour à tous,

Je ne sais pas si j'ai oublié quelquechose mais lorsque j'effectue une recherche la requête Ajax me renvoie tous les résultats sans avoir appliqué le filtre... J'ai essayé avec Match Against mais aussi avec une requête plus simple avec Like, on dirait quue les termes introduits dans le champ de recherche sont ignorés...
Pourtant la requête est bien envoyée à chaque frappe dans le champ de recherche mais renvoie encore tous les résultats (visibles aussi en console)...

Merci d'avance de m'éclairer de vos lumières

ArticlesController.php :

//Rechercher un article
    #[Route('/rechercher-article', 'rechercher-article')]
    public function rechercherArticle(ArticlesRepository $articlesRepository, Request $request): Response
    {
        $form = $this->createForm(RechercherArticleType::class);
        $form->handleRequest($request);

        $articles = $articlesRepository->rechercherArticle($form->get('rechercher')->getData());

        if ($request->isXmlHttpRequest()) {

            return new JsonResponse([
                'content' => $this->renderView('_partials/_rechercher-article.html.twig', [
                    'articles' => $articles
                ])
            ]);
        }

        return $this->render('articles/rechercher-article.html.twig', [
            'form' => $form->createView(),            
            'titre' => 'Rechercher un article / prestation',
            'articles' => $articles
        ]);
    }

rechercher-article.js :

//Recherche d'articles par mots-clés
window.onload = () => {
  const formRecherche = document.querySelector("#formRecherche");
  const rechercher = document.querySelector("#rechercher_article_rechercher");
  const resultatRecherche = document.querySelector("#resultat-recherche");

  rechercher.addEventListener("input", () => {

    if (rechercher.value.length >= 3) {
      const formData = new FormData(formRecherche);
      // formData.append("rechercher", rechercher.value);

      for (item of formData) {
        console.log(item[0], item[1]);
      }

      fetch("rechercher-article", {
        method: "POST",
        body: formData,
        headers: {
          "X-Requested-With": "XMLHttpRequest",
          "Content-type": "application/json; charset=UTF-8",
        },
      })
        .then((response) => response.json())
        .then((data) => {
          // console.log(data.content);
          resultatRecherche.innerHTML = data.content;
        })
        .catch((error) => alert("Erreur : " + error));
    }
  });
};

ArticlesRerpository :

public function rechercherArticle($rechercher)
    {
        $query = $this->createQueryBuilder('a');

        if ($rechercher != null) {
            $query   
            ->andWhere('a.reference LIKE :rechercher')     
                // ->andWhere('MATCH_AGAINST(a.reference,a.description) AGAINST (:rechercher boolean)>0')
                ->setParameter('rechercher','%'.$rechercher.'%')
                ->orderBy('a.reference', 'ASC')
                ;
        }
        return $query->getQuery()->getResult();
    }

12 réponses


Salut,
Dans le debug de symfony tu as quoi comme requète SQL ?
Vu le comportement que tu décris ça laisse penser que ta variable $rechercher est nulle dans la fonction rechercherArticle.

Bonjour et merci d'avoir répondu

La requête semble correcte, (la référence d'exemple AZZ913745 existe bien dans la base et ladite requête retourne bien un résultat dans l'onglet SQL de PHP MyAdmin) , voici ce que renvoie le debugger :

SELECT a0_.reference AS reference_0, a0_.description AS description_1 FROM articles a0_ WHERE a0_.reference LIKE '%AZZ913745%' ORDER BY a0_.reference ASC;

Tout d'abord j'ai remonté le return dans le if de la fonction (maintenant il ne me remonte plus tous les résultats mais le message d'erreur voulu lorsqu'aucune donnée n'est retournée ce qui est normal, par contre si correspondance il y a, aucun résultat n'est affiché, bizarre ... J'ai essayé plusieurs requêtes simplifiées rien n'y fait ... :

    public function rechercherArticle($rechercher)
    {

        $query = $this->createQueryBuilder('a');

        if ($rechercher !== null) {
            $query
                ->select('a.reference,a.description')
                ->andWhere('a.reference LIKE :rechercher')
                // ->andWhere('MATCH_AGAINST(a.reference,a.description) AGAINST (:rechercher boolean)>0')
                ->setParameter('rechercher', '%' . $rechercher . '%')
                ->orderBy('a.reference', 'ASC');

                return $query->getQuery()->getResult();
        }
    }
 J'ai l'impression que ça viendrait plutôt du code JS/Ajax ... Je me demandais si il ne fallait pas préciser que l'on veut envoyer que le champ "recherche" et non pas recherche + token par le formData ? Qu'en penses tu ?

Dans ton controller est ce que tu récupères bien les infos du champ "recherche" ? Si oui je ne pense pas que le token pose problème.

Dans ta requête Ajax tu as mis un console.log qui est en commentaire il t'affiche quoi ?

Bonjour David-CCO,

Alors dans le debugger j'ai bien le contenu du champ de recherche qui s'affiche si je mets

dump($form->get('rechercher')->getData());

Concernant le console.log(rechercher) il affiche aussi la valeur active dans le champ...

Incompréhensible !!!

Je me suis mal exprimé pour le console.log c'est ici qu'il faudrait le tester

.then((data) => {
          console.log(data); <-- ici
          resultatRecherche.innerHTML = data.content;
        })

Merci David-CCO de ton interêt pour mon problème...

Donc le console.log(data) ramène bien un contenu avec le message que j'ai créé dans mon Twig au cas ou $articles serait null, autrement dit la requête ne retourne pas les données escomptées venant de la base.

J'ai essayé cet après midi de changer les clauses de la requête, j'ai vérifié les données en base, rien n'y fait, on dirait que la variable $rechercher n'est pas correctement envoyée dans la fonction du repository et Twig renvoie donc le message d'erreur approprié...
D'ailleurs, j'ai essayé en retirant le body dans le code JS et le message est le même... La variable rechercher ne serait donc pas envoyée ? Problème d'encodage ?

D'autre part si elle était nulle aucun résultat ne devrait être retourné puisqu'il y a un if à cet effet dans la fonction RechercherArticle du repository, à moins que la variable ne soit pas reconnue comme string ? D'ailleurs je ne crois pas que l'on puisse typer une variable placée en paramètre de fonction du repository, j'ai essayé en tous cas et ça n'est pas accepté chez-moi ...

Je voudrais faire un dump sur $form->get('rechercher')->getData() (mis en paramètre de la fonction du repo) mais ça ne marche pas vu que le code Ajax est déclenché...

Il y a donc quelquechose qui ne communique pas ... et je commence à desespérer...

Concernant la variable $rechercher elle n'est peut être pas null mais vide et du coup tu rentres dans ton if. Au lieu de faire

if ($rechercher !== null)

fait

if (!empty($rechercher)

Je pense que tu ne vas plus entrer dans ton if.

Sinon si tu remplaces cette ligne dans ton controller :

$articles = $articlesRepository->rechercherArticle($form->get('rechercher')->getData());

par

$articles = $articlesRepository->rechercherArticle("AZZ913745");

Est ce que ça marche ?
Si oui alors tu seras sûr que ton problème viens du $form->get('rechercher')->getData() mais dans ce cas, je ne comprendrai pas car tu m'as dit plus haut que tu avais fait un dump sur $form->get('rechercher')->getData() et que c'était bon.

Tu pourras me montrer le dump de $form->get('rechercher')->getData() stp ?

Bonjour David-CCO

Alors premièrement en injectant directement un string ($articles = $articlesRepository->rechercherArticle("AZZ913745")) ça retourne bien les bons résultats, même ceux contenant seulement une partie de celui-ci, ce qui est le but recherché... Donc aucun problème à priori dans le repository !

Concernant le dump de $form->get('rechercher')->getData() :

Si je le mets après if ($request->isXmlHttpRequest()) rien ne se passe et l'icône cible du debugger n'est donc pas visible...
Si je le mets avant la condition if, la cible apparait avec 'null'

Cela laisse à penser que non seulement il arrive pas à attraper la valeur du champ de recherche mais qu'en plus il ne reconnaîtrait pas non plus la $request comme étant XmlHTTPRequest alors que les entêtes de réponse disent le contraire !

J'ai essayé de changer le nom du champ de recherche pour celui que me donne l'inspecteur du navigateur à savoir (name="rechercher_article[rechercher]", il ne l'accepte pas...

J'ai même essayé de faire un stringify sur formData pour être sûr que la valeur du champ soit bien envoyée en JSON, rien n'y fait ...

Désespérant ... Et je suis sûr que tout ça c'est un petit détail de rien du tout qui a été oublié ...

Oui tu as raison c'est un problème viens du request.
Si tu fais un dump de $request en analysant le contenu est ce que tu retrouves les données du champ recherche ?

Bonjour de nouveau

Le dump du request me renvoie une foule d'infos mais la variable n'en fait pas partie, d'ailleurs je ne sais comment l'extraire de la request , c'est du charabia pour moi ... Les tableaux de paramètres sont vides ...D'autre part, à moins d'installer un event subscriber + méthode pour actualiser les headers d'une requête Ajax et ainsi pouvoir actualiser les infos dans le debugger je ne vois pas comment on pourrait avoir accès au dump...

De toutes manières ce qui me semble anormal c'est qu'après tests, le "if ($request->isXmlHttpRequest())" paraît renvoyer toujours false, pourtant les headers sont bien envoyés et spécifient qu'on a utilisé le XMLHttpRequest dans la réponse du serveur...

Donc faudrait à mon avis commencer par là car si on ne rentre jamais dans la condition la variable $articles sera envoyée comme empty ou null et Twig renverra le message que j'ai déjà décrit plus haut, message qui apparaît d'ailleurs à la place du résultat de requête dans mon navigateur ... C'est d'ailleurs bizarre qu'il apparaisse car cela laisse à supposer qu'une requête via le repository a quand même eu lieu...

D'autre part, je n'ai toujours pas compris pourquoi Symfony renomme les champs de formulaire à sa guise (c'est peut être normal...) ni comment il fait la liaison entre la variable rechercher du repository et la ligne du formData : "rechercher_article[rechercher] valeur", le problème ne viendrait t'il pas de là aussi ? N'est on pas entrain de lui envoyer une key qui ne porte pas le même nom que la variable que l'on cherche à envoyer ?
Moi je trouverais logique que le formData envoie "rechercher | valeur introduite" plutôt que "rechercher_article[rechercher] | valeur introduite" non ?

Bref, il va falloir exercer nos talents de Sherlock car là ça devient grave ...

Incroyable mais vrai ...
Après des heures d'arrachage de cheveux et investigations, je découvre que c'est la ligne "Content-Type" qui bloquait tout ... Tout marche à merveille maintenant...

Du coup quoi mettre en content type ? rien ?

Salut,

C'est une bonne nouvelle.
Juste pour tester est ce que tu peux mettre Content-Type avec un T majuscule ?