React:liste des produits + load more

folder Projet: VentesReactNodeJS (FullStack :backEndProject et front_end_project)
Remarque: Pour la partie backEndProject en va travailler avec les fonctions déjà créer dans la section liste Produits puis on ajouter fake pour insérer des données dans la table Produit
Dans cette partie on va afficher la liste de produits de la table produit avec la pagination
Produit(id,nom,prix,qteStock)
BackEnd :Nodejs+ExpressJs+mysql:pour créer les RestApis
FrontEnd :React+Axios pour consommer les apis

BackEnd Créer les Apis :backEndProject

  1. 1Créer la méthode afficherNparPage() dans src/models/Produits :permettant d'exécuter la requête Sql :select * from produit limit StartFrom,LigneParPage
  2. 2Créer la méthode afficherNparPage() dans src/controllers/ProduitController:permettant d'appelere la methode afficherNparPage() du model Produit et envoyer le resultat au projet FontEnd de React
  3. 3Ajouter la route :http://localhost:8081/produits/StartFrom/LigneParPage mappé avec la fonction afficherNparPage() du controller ProduitController

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

/**Afficher la liste des produit du page : page**/
Produit.afficherNparPage = (page,LigneParPage,result) =>{

/*Supprimer les non Numérique from les paramètres*/
page=parseInt(page.replace(/\D/g,''));
LigneParPage=parseInt(LigneParPage.replace(/\D/g,''));
console.log(LigneParPage);
/*Limit start,LigneParPage : */
let start=(page-1)*LigneParPage;
connexion.query('SELECT * FROM produit limit ? ,?',[start,LigneParPage] ,(err, res)=>{
if(err){
result(err,null);
}else{
/*retourne la liste des produits*/
result(null,res);
}
})

}

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

/*Afficher LigneParPage produits à partir de la page :page */
exports.afficherNparPage = (req, res)=>{
ProduitModel.afficherNparPage(req.params.page,req.params.LigneParPage, (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

/*Afficher LigneParPage produits à partir de la page :page*/
routerProduits.get('/:page/:LigneParPage', produitController.afficherNparPage);



4.Faker:Insérer des données dans la table Produit

Installer Faker
npm install @faker-js/faker --save-dev
Créer le fichier database/fakeData.js
/*Importer le module mysql qui permet de gérer les transaction dans une base de données mysql */
var mysql = require('mysql2');
const { faker } = require('@faker-js/faker');

var con = mysql.createConnection({
host: "localhost", /*le serveur de la base de données*/
user: "root", /*Utilisateur de la base de données*/
password: "",/*le mot de passe de l'utilisateur de la base de données*/
port: "8111", /*le serveur de la base de données*/
database: "databaseReact" /*le nom de la base de données à Créer manullement*/
});

/*Créer un objet Produit */
var p={id:'',
nom:'',
prix:0,
qtestock:0
};

/*Insérer 50 ligne dans la table produit*/
for(let i=0; i<50; i++){
p.nom = faker.commerce.product();
p.prix = faker.commerce.price();
p.qtestock= faker.datatype.number();
/*Exécuter la requêtes SQL insert into produit*/
con.query("INSERT INTO produit set ?", p, function (err, res) {
if(err) {
console.log("error: ", err);
}

});
}
Exécuter le script database/fakeData.js
node database/fakeData.js
50 lignes sont ajoutées dans la table produit

5.Count: afin de créer LoadMore produits on a besoin de savoir le nombre totale des produit dans la table produits

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

/*nombre de ligne dans la table produit*/
Produit.count = (result)=>{
connexion.query('SELECT count(id) as totale FROM produit', (err, res)=>{
if(err){
result(err, null);
}else{
result(null, res[0]);
}
})
}

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

/*get le nombre totale des produits*/
exports.count = (req, res)=> {
ProduitModel.count((err, n) =>{
if(err)
/*si erreur envoyer l'erreur*/
res.send(err);
/*sinon envoyer la liste des produits*/
res.send(n)
})
}

C.Routes:créer une route pour consomer count() dans src/routes/ProduitRoutes.js

/*get le nombre totale des produits */
routerProduits.get('/n/count/all', produitController.count);

Tester

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

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

React: Créer la component listeLoadMore.js

npx crcf components/Produits/listeLoadMore
import React, { useState,useEffect } from "react";
import ReactDOM from "react-dom";
import axios from "axios";
import {Table} from 'react-bootstrap';


function ListeLoadMore() {
/*listeProduit :contiendra la liste des produit From l'api backend*/
const [listeProduit, setListeProduit] = useState([]);
/*Le numero de la page actuellement afichée*/
const [pageAffiche, setPageAffiche] = useState(1);
/*le nombre de ligne à afficher par page*/
const [ligneParPage, setLigneParPage] = useState(2);
/*Le nombre totale des ligne dans la table produit à intialiser dans useEffect*/
const [totaleLigne, setTotaleLigne] = useState(0);
/*Charger more produits */
const loadMoreItems = () => {
setPageAffiche(pageAffiche+1);
axios.get('http://localhost:8081/apis/produits/'+pageAffiche+'/'+ligneParPage)
//attend er recevoir la réponse du serveur
.then(response => {

setTimeout(() => {
setListeProduit([...listeProduit, ...response.data]);
}, 300);
}
);
}
/*Initialiser la lsite de produit et le totaleLigne*/
useEffect(() => {
/*get le nombre totale de produit from the backend */
axios.get('http://127.0.0.1:8081/apis/produits/n/count/all')
//attend er recevoir la réponse du serveur
.then(response => {
setTotaleLigne(response.data.totale);
/*Charger les produit une fois la componentDidMount :(chargé)*/
loadMoreItems();

}
);
},[]);

return (

<div className="container">
<br/>
<div className="card text-dark card bg-grey mb-3">
<div className="card-header card bg-warning">Load More :La liste des produits</div>
<div className="card-body">
<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>
{ (totaleLigne>(pageAffiche*2)) &&
<button onClick={loadMoreItems} className="btn btn-secondary btn-block">Load More</button>
}
</div>
</div>
</div>

);
}
export default ListeLoadMore;


Ajouter une route 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'
import ListeLoadMore from './components/Produits/listeLoadMore/listeLoadMore.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/>}/>
<Route exact path="/ListeLoadMore" element={<ListeLoadMore/>}/>
</Routes>
</Router>
</div>
);
}

export default App;

Demarer le backEndProject

backEndProject>node Serveur.js

Demarer le front_end_project

font_end_project>npm start