React:Form :Ajouter un produit
Dans cette partie on va créer un formulaire pour ajouter un produit
Produit(id,nom,prix,qteStock)
Afin de créer un projet crud pour gérer les produits on besoin de créer deux type de projet:
BackEnd :Nodejs+ExpressJs+mysql:pour créer les RestApis
FrontEnd :React+Axios pour consommer les apis
- Projet: VentesReactNodeJS :La structure
├──VentesReactNodeJS
│ ├── backEndProject
│ │ ├── config
│ │ │ ├── config.js
│ │ ├──database
│ │ │ ├── createDatabase.js
│ │ ├──src
│ │ │ ├──models
│ │ │ │ ├──Produit.js
│ │ │ │ ├──Utilisateur.js
│ │ │ │ ├──Vente.js
│ │ │ ├──controllers
│ │ │ │ ├──ProduitController.js
│ │ │ │ ├──UtilisateurController.js
│ │ │ │ ├──VenteController.js
│ │ │ ├── routes
│ │ │ │ ├──ProduitRoutes.js
│ │ │ │ ├──UtilisateurRoutes.js
│ │ │ │ ├──VenteRoutes.js
│ ├── serveur.js
│
│
│ ├── front_end_project
│ │
│ │ src ├── App.js
│ │ ├──components
│ │ │ ├──Produits
│ │ │ │ ├──ajouter.js
│ │ │ │ ├──liste.js
│ │ │ │ ├──modifier.js
│ │ │ ├──Utilisateurs
│ │ │ │ ├──ajouter.js
│ │ │ │ ├──liste.js
│ │ │ │ ├──modifier.js
│ │ │ ├── Ventes
│ │ │ │ ├──vendre.js
│ │ │ │ ├──facture.js
│____│_____ _│__│_____├──liste.js
Le projet backEndProject va contenir les traitement métier de notre application FullStack:
backEndProject
├──src
│ ├─models
│ │ ├Produit.js
│ │ ├─objet Produit(id,nom,prix,qtestock)
│ │ ├─insert(produit) :fonction qui permet insert into table
│ │ ├─afficherAll :return select * from produits
│ │ ├─supprimre(id):return delete from produit where id=?
│ │ ├─modifier(id,produit):return upate produit set ? where id=?
│ │ ├─......
│ ├─controllers
│ │ ├─ProduitController.js
│ │ ├─insert(request):appel Produit.insert(produit)
│ │ ├─afficherAll():appel Produit.afficherAll(produit)
│ │ ├─supprimer(request):appel Produit.supprimer(produit)
│ │ ├─modifier(request):appel Produit.modifier(id,produit)
│ │ ├─.....
│ ├─routes
│ │ ├─ProduitRoutes.js
│ │ ├─Route.get('/',ProduitController.afficherAll)
│ │ ├─Route.post('/ajouter',ProduitController.insert)
│ │ ├─Route.get('/:id',ProduitController.detail)
│ │ ├─.....
Le projet front_end_project va contenir des component(View+traitements) qui appel au services du backEndProject
├──front_end_project
│ ├─components
│ ├─Produits
│ ├─ajouter.js
│ │ ├─View :formulaire HTML
│ │ ├─JavaScript JSX:traitements
│ │ ├─ajouter():consome l'api du backEndProject avec AXIOS => insert() du controllers
..............
on aura besoin
-
Node.js et le module mysql pour intéroger la base de données
- le framework Express pour générer les REST APIs
- le module Axios de React pour consommer les Rest Apis crées dans nodeJs project
BackEnd Créer les Apis :backEndProject
Dans cette partie on va créer un projet avec Nodejs+ExpressJS+Mysql afin de créer les RestApi pour :
- 1GET http://localhost:8081/produits :Afficher la liste des produits
- 2POST:http://localhost:8081/produits/add Ajouter un produit
- 3Delete:http://localhost:8081/produits/:id :Supprimer un produit passé en paramètre
- 4PUT: http://localhost:8081/produits/id/modifier :Modifier un produit passé en paramètres
Créer la base de données ventesgestions et table Produit
Installer un SGBD mysql et démarer le service mysql
Télécharger mysql SGBD ,Dans ce tp on utilise Xampp server https://www.apachefriends.org/fr/download.html
mais vous pouvez utilsé n'importe quelle SGBD mysql
Installer le module mysql
Un projet nodeJs utilise plusieurs bibiothèque javasript nommées modules
Afin de travailer avec mysql on doit installer le module mysql
npm install mysql2 --save
Installer ExpressJs
npm install express --save
4.Créer le fichier CreerDBandTables.js
/*Importer le module mysql qui permet de gérer les transaction dans une base de données mysql */
var mysql = require('mysql2');
//créer une connexion à la base de données
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: "3306", /*le serveur de la base de données*/
});
/*Créer la base de données */
con.connect(function(err) {
if (err) throw err;
console.log("Connected!");
con.query("CREATE DATABASE if not exists databaseReact", function (err, result) {
if (err) throw err;
/*se connecter à la base de données crée puis créer les tables */
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: "3306", /*le serveur de la base de données*/
database: "databaseReact" /*le nom de la base de données à Créer manullement*/
});
//se connecter en utlisant con crée
con.connect(function(err) {
/*err:contient error de connexion*/
/*afficher erreur de connexion s'il existe*/
if (err) throw err;
/*pas d'erreur donc on peut exécuter des requête sql */
/*Créer la table produit */
var sql = "CREATE TABLE produit(id int primary key auto_increment,nom varchar(25),prix float,qtestock int)";
/*Exécuter la requete sql crée*/
con.query(sql, function (err, result) {
if (err) throw err;
console.log("Table produit est crée");
});
});
});
});
5.Exécuter le script SQL pour créer la base de données
node createDatabase.js
1.Créer le fichier config/config.js de configuration de la connexion à la base de données
var mysql = require('mysql2');
var connection = mysql.createConnection({
host: "localhost", /*le serveur de la base de données*/
port:"3306",/*le port du service mysql*/
user: "root", /*Utilisateur de la base de données*/
password: "",/*le mot de passe de l'utilisateur de la base de données*/
database: "databaseReact" /*le nom de la base de données à Créer manullement*/
});
//connexion à la base de données
connection.connect(function(error){
if(!!error) {
console.log(error);
} else {
console.log('Connected..!');
}
});
module.exports = connection;
3.Créer le dossie src contenant le code source de l'applications
Afin d'organiser le projet on besoin de créer les dossiers suivants
- src/models :contenant les model du projet produit ,utilisateur et ses fonctions de CRUD
- src/routes :contenant le mapping entre les requêtes http est la méthode à exécuter
- src/controllers :contient les méthode à exécutée selon chaque route reçues
Model: Créer le fichier src/models/Produit.js
Ce fichier représente le module de l'entité produit(id,nom,prix,qtestock) contenant:
- Un objet Produit
- Les fonctions CRUD:
- insert
- update
- delete
- detail
/*importer le fichier de configuration de connexion à la base de données*/
var connexion = require('./../../config/config');
/*Créer un objet de type Produit*/
var Produit = function(produit){
this.id = produit.id;
this.nom = produit.nom;
this.prix = produit.prix;
this.qtestock = produit.qtestock;
};
/**1.insert**/
/*Ajouter à l'objet Produit la fonction insert qui permet d'ajouter un produit dans la table produit*/
Produit.insert = function (produit, result) {
/*produit :sera renseigner par le controlleur contenant l'objet à insérer dans la table produit
result:un objet qui contiendra la réponse à envoyer au controlleur :ProduitController
*/
/*Exécuter la requêtes SQL insert into produit*/
connexion.query("INSERT INTO produit set ?", produit, function (err, res) {
/*
function (err, res):la méthode de callback sera exécuté aprés l'exécution de la commande insert into
err:contient l'erreur sql reçu
res:contient la reponse de la methode query
*/
/*Si la fonction query délenche une erreur*/
if(err) {
console.log("error: ", err);
result(err, null);
}
/*Si la fonction query s'exécute sans erreur on envoie res.insertId :c'est la valeur de la primary key de l'objet inséré */
else{
console.log(res.insertId);
result(null, res.insertId);
}
});
};
//vérifier si un attribut est vide
Produit.verifier=function(produit)
{
if(produit.nom=='' || produit.prix==0 || produit.qtestock==0)
return true;
};
/*Exporter la classe pour pouvoir l'importer dans le controller */
module.exports= Produit;
Controller: Créer le fichier src/controllers/ProduitController.js
Permet de gérer la communication entre le model Produit et les et le projet React :frontEndProject
/*Importer les fonctions insert , update, delete , select... */
const ProduitModel = require('../models/Produit')
/*Insérer un nouveau produit dans la table produit*/
exports.insert = (req, res) =>{
const produit_nouveau = new ProduitModel(req.body);
/*Vérifier si tout les champs sont rempli*/
if(ProduitModel.verifier(produit_nouveau))
{
res.json({status: false, message: 'Erreur le produit non ajouté', data: null})
}else{
ProduitModel.insert(produit_nouveau, (err, produit)=>{
if(err)
/*si erreur envoyer l'erreur*/
res.send(err);
/*si Ok envoyer un objet json de la forme:
{
status:true;
message:"le produit est bien ajouté",
data:id du produit inséré
}
*/
res.json({status: true, message: 'Le produit est bien ajouté', data: produit.insertId})
})
}
}
Routes: Créer le fichier src/routes/ProduitRoutes.js
/*importer express js pour manipuler les routes*/
const express = require('express');
/*importer le module Router de express js*/
const routerProduits = express.Router();
/*imporer produitController*/
const produitController = require('../controllers/ProduitController');
/*la route:=> produits/ajouter ,avec la méthode POST
ajouterValider:=>la fonction du ProduitController qui permet d'insérer un produit dans la table produit*/
routerProduits.post('/ajouter', produitController.insert);
module.exports = routerProduits
Serveur Nodejs: Créer le fichier Serveur.js
Permettant de demarer le serveur des APIs
Installer cors
npm install cors --save
const express = require('express');
const bodyParser = require('body-parser');
/*Pemert d'authoriser la consommation des api à partir d'un autre serveur
dans ce cas projet React */
const cors = require('cors');
const app = express();
/*activer le cros domaine */
app.use(cors())
const port = 8081;
// activer le traitement des request de type application/x-www-form-rulencoded
app.use(bodyParser.urlencoded({extended: false}));
//activer le traitement des request de type application/json
app.use(bodyParser.json());
//importer le fichier de routage pour le produit
const produitRoutes = require('./src/routes/ProduitRoutes');
/*Créer les apis pour Produit*/
app.use('/apis/produits/', produitRoutes );
/*Démarer le serveur backEnd*/
app.listen(port, ()=>{
console.log('Serveur est démaré ${port}');
});
FrontEnd Créer les Vues :front_end_project
Créer un projet React
npx create-react-app font_end_project
Créer la component produits/ajouter
On peut créer les component manuellement (un fichier .js) mais afin d'accélérer et simplifier la création des component on install:
npm install --save-dev create-react-component-folder
Puis pour créer la component produits/ajouter on se positionnne dans le dossier src puis on lance la commande
cd src
npx crcf components/Produits/ajouter
/*ajouter.js:le contenu par défaut */
import React, { Component } from "react";
class Ajouter extends Component {
render() {
return <div>Ajouter</div>;
}
}
export default Ajouter;
Installer bootstrap
npm install react-bootstrap bootstrap@5.1.3
Le dossier
node_modules\bootstrap est crée contenant les style boostrap
l'étape suivante est ajoute bootstrap.css dans la component principale App.js
et importer la component navigation.js
import './App.css';
/*importer les styles boostrap*/
import 'bootstrap/dist/css/bootstrap.min.css';
/*importer la component ajouter*/
import Ajouter from './components/Produits/ajouter'
function App() {
return (
/*Ajouter la component ajouter.js*/
<div>
<Ajouter/>
</div>
);
}
export default App;
Installer Axios
npm install axios --save
Modifier le fichier ajouter.js en ajoutant le formulaire pour ajouter un produit
import React, { Component } from "react";
import axios from "axios";
class Ajouter extends Component {
constructor(props) {
super(props);
/*Créer le state du component*/
this.state = {
produit:{
id: null,
nom: "",
qtestock:0,
prix:0
},
message:"",/*Stocker la réponse du serveur*/
statusResponse:""/*Stocker l'état de la reponse 200,404..*/
};
/*Enregister la méthode changerEtat*/
this.changerEtat = this.changerEtat.bind(this);
}
changerEtat(event) {
this.setState({produit:{
...this.state.produit,
/*changer la valeur de l'attribut
[event.target.name]=><input name="nom"
event.target.value => input value=""*/
[event.target.name]: event.target.value
}});
}
/*Envoyer un nouveau produit*/
ajouterProduit = async e => {
await axios.post('http://localhost:8081/apis/produits/ajouter', this.state.produit)
.then(response => {
/*est la réponse du serveur nodejs :
data: {status: true, message: 'Le produit est bien ajout�'}
headers: {content-length: '56', content-type: 'application/json; charset=utf-8'}
request: XMLHttpRequest {onreadystatechange: null, readyState: 4, timeout: 0, withCredentials: false, upload: XMLHttpRequestUpload, …}
status: 200
statusText: "OK"
*/
//Changer le State
this.setState({statusResponse:response.data.status,
message:response.data.message});
/*le produit est bien ajouté initialiser les input et l'objet produit du sate*/
if(this.state.statusResponse==true)
{
this.setState({produit:{
...this.state.produit,
nom: "",
prix: 0,
qtestock: 0
}});
}
});;
};
render() {
let couleur="";
if (this.state.statusResponse==true) {
couleur ="alert alert-success";
}
if (this.state.statusResponse==false) {
couleur ="alert alert-danger";
}
return (
<div className="container">
<div className="row">
<fieldset className="border p-2">
{/*Afficher le message si on a reçu une reponse serveur*/}
{this.state.message.length > 0 &&
<div className={ couleur} role="alert">
{this.state.message}
</div>
}
<legend className="w-auto">Ajouter un produit</legend>
<div className="form-group mb-3">
<input
type="text"
className="form-control"
placeholder="Enter le nom"
name="nom"
value={this.state.produit.nom}
onChange={e => this.changerEtat(e)} />
</div>
<div className="form-group mb-3">
<input
type="number"
className="form-control"
placeholder="Enter le prix"
name="prix"
value={this.state.produit.prix}
onChange={e => this.changerEtat(e)}/>
</div>
<div className="form-group mb-3">
<input
type="number"
className="form-control"
placeholder="Enter le qtestock"
name="qtestock"
value={this.state.produit.qtestock}
onChange={e => this.changerEtat(e)} />
</div>
<button onClick={this.ajouterProduit} className="btn btn-secondary btn-block">Ajouter</button>
</fieldset>
</div>
</div>
);
}
}
export default Ajouter;
Demarer le backEndProject
backEndProject>node Serveur.js
Demarer le front_end_project
font_end_project>npm start