React:Recherche et AutoComplete

folder Projet: VentesReactNodeJS (FullStack :backEndProject et front_end_project)
Dans cette partie on va chercher un produit en utilisant autoComplete puis afficher les détails du produit trouvé
Produit(id,nom,prix,qteStock)
BackEnd :Nodejs+ExpressJs+mysql:pour créer les RestApis
FrontEnd :React+Axios+react-autocomplete pour consommer les apis

BackEnd Créer les Apis :backEndProject

  1. 1Créer la méthode chercherParNom() dans src/models/Produits :permettant d'exécuter la requête Sql :select * from produit nom like '%%'
  2. 2Créer la méthode ChercherParNom() dans src/controllers/ProduitController:permettant d'appelere la methode ChercherParNom() du model Produit et envoyer le resultat au projet FontEnd de React
  3. 3Ajouter la route :http://localhost:8081/produits/Search/Nom mappé avec la fonction ChercherParNom() du controller ProduitController
  4. 5Créer la méthode produitsNom() permettant de récupérer les noms de tous les produits ,elle sera utilisée avec autoComplete
  5. 6Créer la méthode produitsNom() dans src/controllers/ProduitController:permettant d'appelere la methode produitsNom() du model Produit et envoyer le resultat au projet FontEnd de React

1.Model:créer la fonction chercherParNom() dans src/models/Produit.js

/**Chercher par Nom**/
Produit.chercherParNom = (nom,result) =>{
nom=nom.replace("'", '');
connexion.query("SELECT * FROM produit where nom like ?",'%'+nom+'%' ,(err, res)=>{
if(err){
result(null,err);
}else{
/*retourne la liste des produits*/
result(null,res);
}
})
}

2.Controller: Créer la fonction chercherParNom() dans src/controllers/ProduitController.js

/*Chercher par le nom */
exports.chercherParNom = (req, res)=>{
ProduitModel.chercherParNom(req.params.nom, (err, produits)=>{
if(err)
/*si erreur envoyer l'erreur*/
res.send(err);
/*sinon envoyer la liste des produits*/
res.send(produits)
})
}

3.Routes: ajouter la ligne de routage dans src/routes/ProduitRoutes.js

/*Chercher par Nom*/
routerProduits.get('/search/q/:nom', produitController.chercherParNom);

4.Model:créer la fonction produitsNom() dans src/models/Produit.js

/**Afficher les noms de tout les produits**/
Produit.produitsNom = (result) =>{
connexion.query('SELECT nom FROM produit', (err, res)=>{
if(err){
result(null,err);
}else{
/*retourne la liste des produits*/
result(null,res);
}
})

}

4.Controller :créer la fonction produitsNom() dans src/controllers/ProduitController.js

/*Afficher les nom de tout les produits*/
exports.produitsNom = (req, res)=> {
ProduitModel.produitsNom((err, produits) =>{
if(err)
/*si erreur envoyer l'erreur*/
res.send(err);
/*sinon envoyer la liste des produits*/
res.send(produits)
})
}

5.Routage : Créer une route pour la méthode produitsNom()

/*Afficher les noms de tous les produits*/
routerProduits.get('/search/all/nom', produitController.produitsNom);

2.FrontEnd créer la vue recherche.js dans le projet :front_end_project

  1. 1Créer la components src/components/Produits/rechercher permettant d'afficher le tableau d'object envoyer la méthode chercherParNom() du controller ProduitController du projet backEndProject

React: installer le module react-autocomplete

npm i react-autocomplete-hint --save

React: Créer la component rechercher.js

npx crcf components/Produits/rechercher
import axios from "axios";
import { Hint } from 'react-autocomplete-hint';
import React, {useEffect, useState} from 'react';
import {Table} from 'react-bootstrap';

function Rechercher() {


/**1.Initialiser les variables du State**/
const [lesNoms, setLesNoms] = useState([])
const [listeProduit, setListeProduit] = useState([])
const [listeNoms, setListeNoms] = useState([])
const [text, setText] = useState('')


/**2.Récupérer les noms des produits**/
/*Appler l'api pour récupérer la liste des nom des produit da la base de donnes*/
const produitsNom = async () => {
const res = await axios.get('http://127.0.0.1:8081/apis/produits/search/all/nom');
/*Convertir res (un tableua d'objet [{nom:'...'},{}]
vers un tableau de string ['..','..']
*/
var t = []
res.data.map(a => t.push(a.nom))
setLesNoms(t)
}



/**3.Appeler le backend pour chercher la liste des produits dont leur nom contient le text saisi**/
/*Appler l'api pour récupérer la liste des produit da la base de donnes*/
const chercherParNom = async () => {
axios.get('http://localhost:8081/apis/produits/search/q/'+text)
//attend er recevoir la réponse du serveur
.then(response => {
//changer l'état du state afin de remplir le tableau listeProduit
setListeProduit(response.data);
});
}



/**4.Appler useEffect pour **/
/*
1.Appler produitsNom() pour charger la liste des noms au lancement de component
2.si le text saisie est non vide exécuter la fonction chercherParNom() qui permet de chercher les produits dont leur nom contient la chaine text
3.la fonction useEffect() s'exécute dans une boucle infinie dans pour limiter son exécution on ajoute [text,listeProduit]
pour limiter son Reéxécution seulement lorsque il y a changement dans ces objets du State
*/
useEffect(() => {
produitsNom();
if(text!='')
{
chercherParNom();
}
}, [text,listeProduit]);



/**5.Afficher la vue **/
return(

<div className="container"><br/>

{/**6.Afficher la liste des produit pour un titre indicatif **/}
<div className="card text-center">
<div className="card-header">
Pour info
</div>
<div className="card-body">
<code>{`[${lesNoms.toString()}]`}</code>
</div>
</div>


{/**7.Afficher l'input de rechercher avec un Hint de autocomplete **/}

<div className="card text-center">
<div className="card-header">
CherCher par Nom
</div>
<div className="card-body">
<Hint options={lesNoms} allowTabFill>
<input className='input-with-hint form-control' value={text}
onChange={e => setText(e.target.value)}
/>
</Hint>
</div>
</div>
{/**8.Afficher la liste des produits trouvés **/}
<h3>La liste des produits dont leur nom contient:{text}</h3>
<Table striped bordered hover>
<thead>
<tr>
<th>#</th>
<th>Nom</th>
<th>qteStock</th>
<th>prix</th>
</tr>
</thead>
<tbody>
{/*Boucler sur la tableau et afficher son contenu*/}
{listeProduit.map(p=>(
<tr>
<td>{p.id}</td>
<td>{p.nom}</td>
<td>{p.qtestock}</td>
<td>{p.prix}</td>
</tr>
))}
</tbody>
</Table>
</div>);

}

export default Rechercher;


React: ajouter la route du component rechercher.js dans le fichier App.js

import './App.css';
/*des classe qui permet de créer des routes pour
/produits/ajouter/
/produits/
....
*/
import {
BrowserRouter as Router,
Route,
Routes
} from "react-router-dom";


/*importer les styles boostrap*/
import 'bootstrap/dist/css/bootstrap.min.css';
/*Importer les components*/
import Ajouter from './components/Produits/ajouter/ajouter.js'
import ListeProduitAvecDatatable from './components/Produits/ListeProduitAvecDatatable/ListeProduitAvecDatatable.js'
import ListePagination from './components/Produits/listePagination/listePagination.js'
import Liste from './components/Produits/liste/liste.js'
import Details from './components/Produits/details/details.js'
import Navigation from './components/navigation/navigation.js'
import Rechercher from './components/Produits/rechercher/rechercher.js'

function App() {
return (
<div>
{/*Définir un router */}

<Router>
<Navigation/>
<Routes>
<Route exact path="/produits/" element={<Liste/>}/>
<Route exact path="/produits/ajouter" element={<Ajouter/>}/>
<Route exact path="/produits/:id" element={<Details/>}/>
<Route exact path="/produitsListe" element={<ListePagination/>}/>
<Route exact path="/produitsDatatable" element={<ListeProduitAvecDatatable/>}/>
<Route exact path="/Rechercher" element={<Rechercher/>}/>
</Routes>
</Router>


</div>
);
}

export default App;

Demarer le backEndProject

backEndProject>node Serveur.js

Demarer le front_end_project

font_end_project>npm start