Angular:CRUD :Nodejs, ExpressJS, Mysql

Dans cette partie va travailler avec Angular et Nodejs ,ExpressJs et Mysql pour créer une application Crud de gestion des ventes dans le schéma relationnelle est la suivantes
Partie1:
  1. 1.Création de la base de données
  2. 2.backEnd pour connexion et inscription
  3. 3.FrontEnd pour connexion et inscription
CREATE DATABASE ventesappDB;
CREATE table roles(
id int primary key AUTO_INCREMENT,
nom varchar(25) not null unique
)

CREATE TABLE utilisateurs (
id int(11) NOT NULL AUTO_INCREMENT,
nom varchar(25) not null,
email varchar(25) unique not null,
idRole int not null,
active boolean default 0,
password varchar(250) not null,
photo varchar(100) unique not null,
constraint foreign key(idrole) references roles(id) on delete cascade on update cascade
)

CREATE table produits(
id int primary key AUTO_INCREMENT,
nom varchar(25) not null,
marque varchar(25) not null,
prix float default 0,
qtestock float default 0
)


CREATE table ventes(
id int primary key AUTO_INCREMENT,
idproduit int not null,
idUtilisateur int not null,
datevente date not null,
qteVendue float,
constraint foreign key(idproduit) references produits(id) on delete cascade on update cascade,
constraint foreign key(idUtilisateur) references utilisateurs(id) on delete cascade on update cascade
)

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 :Angular pour consommer les apis
  1. Projet: VentesAngularNodeJSMysql :La structure
  2. ├──VentesAngularNodeJSMysql
    │    ├── 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
    │    
    │  
    │    ├── frontEndproject
    │    │     
    │    │   src ├── App.js
    │    │       ├──components
    │    │       │  ├──Produits
    │    │       │  │     ├──ajouter.js
    │    │       │  │     ├──liste.js
    │    │       │  │     ├──modifier.js
    │    │       │  │     ├──...
    │    │       │  ├──Utilisateurs
    │    │       │  │     ├──inscription.js
    │    │       │  │     ├──connexion.js
    │    │       │  │     ├──...
    │    │       │  ├── Ventes
    │    │       │  │     ├──vendre.js
    │    │       │  │     ├──facture.js
    │____│_____ _│__│_____├──liste.js
    
    
    
    
Le projet backEndProject va contenir les traitement métier de notre application FullStack:

on aura besoin

  1. Node.js et le module mysql pour intéroger la base de données
  2. le framework Express pour générer les REST APIs

BackEnd Créer les Apis :backEndProject

Créer le projet backend

mkdir backEndProject
cd backEndProject
npm init
package name: (backendproject) package.json
puis click entrer

Dans cette partie on va créer un projet avec Nodejs+ExpressJS+Mysql afin de créer les RestApi pour :

  1. 1Post http://localhost:8081/utilisateurs/connexion:connexion d'un utilisatuer
  2. 2Post:http://localhost:8081/utilisateurs/inscription : Inscription d'un utilisateur

Afin de travailer avec mysql on doit installer le module mysql

npm install mysql2 --save

Installer ExpressJs

npm install express --save

Installer md5 utilisé pour le cryptage du password

npm install md5

Installer express-fileupload

npm install express-fileupload

Installer jsonwebtoken

npm install jsonwebtoken

Installer util

npm install util

4.Créer le fichier database/CreerDBandTables.js

/*Importer le module mysql qui permet de gérer les transaction dans une base de données mysql */
var mysql = require('mysql2');
const md5 = require('md5');

//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 ventesappDB", 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: "ventesappDB" /*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 if not exists roles(id int primary key AUTO_INCREMENT,nom varchar(25) not null unique )";
/*Exécuter la requete sql crée*/
con.query(sql, function (err, result) {
if (err) throw err;
console.log("Roles produit est crée");
});
});

//insérer un jeu de teste
con.connect(function(err) {
if (err) throw err;
var sql = "insert into roles(id,nom) values(1,'Amin')";
con.query(sql, function (err, result) {
if (err) throw err;
console.log("Bien inséré");
});
});


con.connect(function(err) {
if (err) throw err;
var sql = "CREATE TABLE if not exists utilisateurs (id int primary key NOT NULL AUTO_INCREMENT,nom varchar(25) not null,email varchar(25) unique not null,password varchar(250) not null,photo varchar(100) not null,active boolean default 0,idRole int null,constraint foreign key(idrole) references roles(id) on delete cascade on update cascade)";
con.query(sql, function (err, result) {
if (err) throw err;
console.log("Table utilisateurs est crée");
});
});


//insérer un utilisateur Admin
con.connect(function(err) {
if (err) throw err;
//crypter le mot de passe
let password_Cryptee="fixabc";
password_Cryptee = md5(password_Cryptee.toString());

var sql = "insert into utilisateurs(id,nom,email,idRole,active,photo,password)values(1,'superAdmin','email@Fixwins',1,1,'pic1.jpg','"+password_Cryptee+"')";
con.query(sql, function (err, result) {
if (err) throw err;
console.log("Bien inséré");
});
});


con.connect(function(err) {
if (err) throw err;
var sql = "CREATE table if not exists produits(id int primary key AUTO_INCREMENT, nom varchar(25) not null, marque varchar(25) not null,prix float default 0,qtestock float default 0)";
con.query(sql, function (err, result) {
if (err) throw err;
console.log("Table produits est crée");
});
});



con.connect(function(err) {
if (err) throw err;
var sql = "CREATE table if not exists ventes( id int primary key AUTO_INCREMENT,idproduit int not null,idUtilisateur int not null,datevente date not null,qteVendue float,constraint foreign key(idproduit) references produits(id) on delete cascade on update cascade, constraint foreign key(idUtilisateur) references utilisateurs(id) on delete cascade on update cascade )";
con.query(sql, function (err, result) {
if (err) throw err;
console.log("Table ventes est crée");
});
});



});
});

5.Exécuter le script SQL pour créer la base de données

node CreerDBandTables.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: "ventesappDB" /*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

  1. src/models :contenant les model du projet utilisateur ,utilisateur et ses fonctions de CRUD
  2. src/routes :contenant le mapping entre les requêtes http est la méthode à exécuter
  3. src/controllers :contient les méthode à exécutée selon chaque route reçues

Model: Créer le fichier src/models/Utilisateur.js

Ce fichier représente le module de l'entité utilisateur(id,nom,email,password,photo,active) contenant:

  1. Un objet Utilisateur
  2. 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 Utilisateur*/
var Utilisateur = function(utilisateur){
this.id = utilisateur.id;
this.nom = utilisateur.nom;
this.email = utilisateur.prix;
this.password = utilisateur.password;
this.photo = utilisateur.photo;
this.active = utilisateur.active;
this.idRole= utilisateur.idRole;
};


/**1.connexion**/
Utilisateur.insert = function (utilisateur_nouveau, result) {
console.log(utilisateur_nouveau);
connexion.query("INSERT INTO utilisateurs(email,nom,password,idrole,photo) values(?,?,?,?,?)", [utilisateur_nouveau.email,utilisateur_nouveau.nom,utilisateur_nouveau.password,utilisateur_nouveau.idRole,utilisateur_nouveau.photo], function (err, res) {
if(err) {
console.log("error: ", err);
result(err, null);
}
else{
console.log(res.insertId);
result(null, res.insertId);
}
});


}



/**Connexion**/
Utilisateur.connexion = (email,password,result) =>{
connexion.query('SELECT * FROM utilisateurs WHERE email=? and password=? ', [email,password], (err, res)=>{
if(err){
result(null, err);
}else{
result(null, res);
// console.log(res);
}
})
}


//vérifier si un attribut est vide
Utilisateur.verifier=function(utilisateur)
{
if(utilisateur.nom=='' || utilisateur.marque=='' || utilisateur.prix==0 || utilisateur.qtestock==0)
return true;
};



/*Exporter la classe pour pouvoir l'importer dans le controller */
module.exports= Utilisateur;

Controller: Créer le fichier src/controllers/UtilisateurController.js

Permet de gérer la communication entre le model Utilisateur et les et le projet Angular :frontEndProject

const UtilisateurModel = require('../models/Utilisateur');
/*Permet de gérer les chemin des dossier et les fichiers*/
var path = require("path");
const md5 = require('md5');
const jwt = require('jsonwebtoken');
/*Insérer un nouveau utilisateur dans la table utilisateur*/
exports.insert = (req, ress) =>{
if(req.body.constructor === Object && Object.keys(req.body).length === 0){
ress.send({ status: 0, data: err });
}else{
// console.log(req.body);


let utilisateur_nouveau = {
nom: '',
email: '',
idRole:'',
password: '',
photo:'',
active:0,
}


//récupérer userInfo envoyé par Angular
utilisateur_nouveau=JSON.parse(req.body.userInfo);
//Crypter le mot de passe
utilisateur_nouveau.password=md5(utilisateur_nouveau.password);

/*Récupérer le fichier */
const file = req.files.file;
const fileName = file.name;
let chemin=path.join(__dirname, '..', '..');
chemin = chemin+ "\\public\\photo_Utilisateurs\\";

/*file.move file to chemin*/
file.mv(chemin+"\\"+fileName, (err) => {
if (!err) {
/*Ajouter photo à l'objet utilisateur reçu*/
utilisateur_nouveau.photo="photo_Utilisateurs/"+fileName;

/*Appler la méthode insert du UtilisateurModel*/
UtilisateurModel.insert(utilisateur_nouveau, (err2, utilisateur)=>{
console.log("utilisateur_nouveau");
console.log(utilisateur_nouveau);
if(err2){
console.log(err2);
ress.send({ status: 0, data: err2 });
}else{
//let token = jwt.sign({ data:utilisateur }, 'secret')
ress.send({ status: 2, data: "ok"});
}

});
}
else
{
ress.send({ status: 0, data: err2 });
}
});
}
}




exports.connexion = (req, ress) =>{
if(req.body.email=='' && req.body.password==''){
res.send({ status: 0, data: err });
}
else{

const email=req.body.email;
const password=md5(req.body.password.toString());
UtilisateurModel.connexion(email,password, (err2, utilisateur)=>{
//si Erreur
if(err2){
ress.send({ status: 0, data: "Erreur de insert" });
}
//si OK
else{
//vérifier si login et password sont correcte
if(utilisateur.length>0)
{
//Vérifier si le compte de l'utilisateur est active
if(utilisateur[0].active==1)
{
let token = jwt.sign({ data: utilisateur }, 'secret')
ress.send({ status: 1, data: utilisateur, token: token });
}
//le compte existe mais n'est pas active
else
{
ress.send({ status: 2, data: "non active" });
}
}
//Login incorrecte
else
{
ress.send({ status: 0, data: "erreur login"});

}
}

});
}
}



middleware: Créer le fichier src/middleware/auth.js

Permettant de sécuriser l'accés aux APIs
const jwt = require('jsonwebtoken')
module.exports.verifyToken = (req, res, next) => {
if (!req.headers.authorization) {
res.status(401).send({ message: "Unauthorized" })
} else {
jwt.verify(req.headers.authorization, "secret", function (err, decoded) {
if(decoded){
req.user = decoded.data
next()
}else{
res.status(401).send({ message: "Unauthorized" })
}
})
}
}

Routes: Créer le fichier src/routes/UtilisateurRoutes.js

/*importer express js pour manipuler les routes*/
const express = require('express');
/*importer le module Router de express js*/
const routerUtilisateurs = express.Router();
/*imporer utilisateurController*/
const utilisateurController = require('../controllers/UtilisateurController');

routerUtilisateurs.post('/inscription', utilisateurController.insert);


routerUtilisateurs.post('/connexion', utilisateurController.connexion);


//tester la connexion
const auth = require('../middleware/auth');
routerUtilisateurs.get('/profile', auth.verifyToken, async (req, res) => {
});

module.exports = routerUtilisateurs

Model: Créer le fichier src/models/Role.js

Ce fichier représente le module de l'entité Role(id,nom) contenant:

  1. Un objet Role
  2. Les fonctions CRUD:
    • insert
    • update
    • delete
    • detail
    • all
/*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 Role = function(role){
this.id = role.id;
this.nom = role.nom;
};

/**1.insert**/
/*Ajouter à l'objet Role la fonction insert qui permet d'ajouter un role dans la table role*/
Role.insert = function (role, result) {
/*role :sera renseigner par le controlleur contenant l'objet à insérer dans la table role
result:un objet qui contiendra la réponse à envoyer au controlleur :RoleController
*/
/*Exécuter la requêtes SQL insert into role*/
connexion.query("INSERT INTO roles set ?", role, 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);
}
});


}

/**Afficher tout les roles**/
Role.afficherAll = (result) =>{
connexion.query('SELECT * FROM roles', (err, res)=>{
if(err){
result(null,err);
}else{
/*retourne la liste des roles*/
result(null,res);
}
})

}


//vérifier si un attribut est vide
Role.verifier=function(role)
{
if(role.nom=='')
return true;
};



/*Exporter la classe pour pouvoir l'importer dans le controller */
module.exports= Role;

Controller: Créer le fichier src/controllers/RoleController.js

const RoleModel = require('../models/Role');
/*Insérer un nouveau role dans la table role*/
exports.insert = (req, res) =>{
const role_nouveau = new RoleModel(req.body);
console.log(req.body);
/*Vérifier si tout les champs sont rempli*/
if(req.body.constructor === Object && Object.keys(req.body).length === 0){
res.send(400).send({success: false, message: 'Erreur tous les champs sont obligatoires'});
}else{
RoleModel.insert(role_nouveau, (err, role)=>{
if(err)
/*si erreur envoyer l'erreur*/
res.send(err);
/*si Ok envoyer un objet json de la forme:
{
status:true;
message:"le role est bien ajouté",
data:id du role inséré
}
*/
res.json({status: true, message: 'Le role est bien ajoute', data: role.insertId})
})
}
}




/*Afficher tout les roles*/
exports.afficherAll = (req, res)=> {
RoleModel.afficherAll((err, roles) =>{
if(err)
/*si erreur envoyer l'erreur*/
res.send(err);
/*sinon envoyer la liste des roles*/
res.send(roles)
})
}

Route: Créer le fichier src/routes/RoleRoutes.js
/*importer express js pour manipuler les routes*/
const express = require('express');
/*importer le module Router de express js*/
const routerRoles = express.Router();
/*imporer roleController*/
const roleController = require('../controllers/RoleController');


/*Afficher tout les role*/
routerRoles.get('/', roleController.afficherAll);



//sécuriser l'accés à la route ajouter un role
const auth = require('../middleware/auth');
/*la route:=> roles/ajouter ,avec la méthode POST */
//routerRoles.post('/ajouter', roleController.insert);
routerRoles.post('/ajouter', auth.verifyToken, async (req, res) => {
roleController.insert(req,res);
});


module.exports = routerRoles
Tester afficher liste Roles

Tester afficher ajouter un role



Serveur Nodejs: modifier 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');
const fileupload = require("express-fileupload");





/*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())

/*activer fileupload*/
app.use(fileupload());

/*Définir le dossier /public en tant qu'un dossier public So on a pas besoin de passer par
le controller afin d'afficher son contenu
*/
app.use('/public', express.static('public'))

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());
app.use(express.json());

//importer le fichier de routage pour les utilisateurs
const routerUtilisateurs = require('./src/routes/UtilisateurRoutes');
/*Créer les apis pour Utiliatuer*/
app.use('/apis/utilisateurs/', routerUtilisateurs);


//importer le fichier de routage pour les roles
const routerRoles = require('./src/routes/RoleRoutes');
/*Créer les apis pour Utiliatuer*/
app.use('/apis/roles/', routerRoles);

/*Démarer le serveur backEnd*/
app.listen(port, ()=>{
console.log('Backend is live port : 8081');

});

FrontEnd Créer les Vues :front_end_project

Créer un projet Angular :frontEndproject

ng new frontEndProject

1.Créer un services qui permet de comsomer l'api

ng g service services/api

services/api.service.ts

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { map } from 'rxjs/operators';
@Injectable({
providedIn: 'root'
})
export class ApiService {
baseUrl = 'http://localhost:8081/apis/';
constructor(private _http: HttpClient) {
}

//permet d'éxécuter une méthode post et retourne le résultat
post(url:string, param:any) {
return this._http.post(this.baseUrl+""+url, param).pipe(map(res => {
return res;
}));
}

//exécuter des get dans le serveur
get(url:string) {
return this._http.get(this.baseUrl+""+url).pipe(map(res => {
return res;
}));
}

}

services/auth.service.ts

Permet de vérifier si l'utilisateur est connecter ou pas

ng g service services/auth
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class AuthService {
constructor() { }
//vériier si l'utilisateur est déja connecté
getUserDetails() {
if(localStorage.getItem('utilisateurInfos')){
return localStorage.getItem('utilisateurInfos')
}else{
return null
}
}
setDataInLocalStorage(variableName:string, data:string) {
localStorage.setItem(variableName, data);
}

//récupérer le token from localStorage
getToken() {
return localStorage.getItem('token');
}

//déconnecter et vider le localStorage
clearStorage() {
localStorage.clear();
}
}

services/auth-guard.service.ts

auth-guard:un midlleware qui sera appeler pour chaque route dans le fichier de RouteConfigLoadEnd pour vérifier est ce que l'utilisateur est connecté ou pas

ng g service services/auth-guard
import { Injectable } from '@angular/core';
import { ActivatedRouteSnapshot, RouterStateSnapshot, Router, RouteConfigLoadEnd } from '@angular/router';
import { Observable } from 'rxjs';
import { AuthService } from './auth.service';
@Injectable({
providedIn: 'root'
})
export class AuthGuardService {
constructor(
private _authService: AuthService,
private _router: Router
) { }

canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {
//si connecter vous pouvez continuer vers la route voulue
if (this._authService.getToken()) {
return true;
}
//si on vous devrez se connecter
this._router.navigate(['/login']);
return false;
}
}

app-routing.module.ts

import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { LoginComponent } from './auth/components/login/login.component';
import { RegisterComponent } from './auth/components/register/register.component';
import { ProfileComponent } from './components/profile/profile.component';
import { AuthGuardService } from './services/auth-guard.service';
const routes: Routes = [
//les routes publiques
{path: 'login', component: LoginComponent},
{path: 'register', component: RegisterComponent},
//une route privé controllé par AuthGuardService
{path: 'profile', canActivate: [AuthGuardService], component: ProfileComponent},
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }

auth/auth/auth.module.ts

le module auth.module permet de gérer les imports et provider liées aux component login et register

ng g module auth/auth
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { LoginComponent } from '../components/login/login.component';
import { RegisterComponent } from '../components/register/register.component';
import {FormsModule, ReactiveFormsModule} from '@angular/forms'
import { HttpClientModule } from '@angular/common/http';
@NgModule({
declarations: [
LoginComponent,
RegisterComponent
],
imports: [
CommonModule,
ReactiveFormsModule,
FormsModule,
HttpClientModule
],
exports: [
LoginComponent,
RegisterComponent
]
})
export class AuthModule { }

auth/components/login/login.component.ts

Créer la component login permettant à un utilisateur inscrit de se connecter avec son email et mot de passe

ng g component auth/components/login
import { Component, OnInit } from '@angular/core';
import {NgForm} from '@angular/forms';
import { ApiService } from './../../../services/api.service'
import { AuthService } from './../../../services/auth.service'
import { Router } from '@angular/router';
@Component({
selector: 'app-login',
templateUrl: './login.component.html',
styleUrls: ['./login.component.css']
})
export class LoginComponent implements OnInit {
isLogin: boolean = false;
status:number=0;
messageStatus:string="";

constructor(
private _api: ApiService,
private _auth: AuthService,
private _router:Router
) { }

//vérifier si l'utilisateur est connecté
ngOnInit() {
this.isUserLogin();
}
//lorsque on cliquer sur se connecter
onSubmit(form: NgForm) {
console.log('Données envoyé ', form.value);
this._api.post('utilisateurs/connexion', form.value).subscribe((res: any) => {
console.log(res);
this.status=res.status;
//1.utilisateur connecté et compte est active
if (this.status==1) {
this._auth.setDataInLocalStorage('utilisateurInfos', JSON.stringify(res.data));
this._auth.setDataInLocalStorage('token', res.token);
this._router.navigate(['/']);
window.location.reload();
}
//2.utilisateur connecté et compte Mais compte n'est active
else if (this.status==2) {
this.messageStatus="Votre compte n'est pas active pour le moment";
}
//3.Erreur de login et password
else if (this.status==0) {
this.messageStatus="Erreur login ou password sont incorrectes";
}
})
}

//vérifier si le localStage !=null
isUserLogin(){
if(this._auth.getUserDetails() != null){
this.isLogin = true;
}
}

//vider localStorage
logout(){
this._auth.clearStorage()
this._router.navigate(['']);
window.location.reload();
}
}

auth/components/login/login.component.html

1.installer bootsrap
Command:
npm install bootstrap --save
2.Ajouter bootsrap dans le fichiers de dépendances angular.json
"styles": [ "src/styles.css", "./node_modules/bootstrap/dist/css/bootstrap.min.css" ]
"scripts": [ "./node_modules/bootstrap/dist/js/bootstrap.min.js"]
-Maintenant toutes les components du projet peuvent utilser les classes de bootsrap

<div class="card text-center ">
<div class="card-header bg-info">
Login
</div>
<div class="card-body">
<h2 *ngIf = 'this.isLogin' class="bg-success">Vous êtes connecté</h2>
<h3 *ngIf = 'this.status==0 || this.status==2' class="bg-danger">{{this.messageStatus}}</h3>
<div class="card-text" *ngIf = '!this.isLogin || this.status==2'>
<form #myform = "ngForm" (ngSubmit) = "onSubmit(myform)" >
<div class = 'form-group' style="padding:5px;">
<input class = 'form-control' type = "text" name = "email" placeholder = "email" ngModel>
</div>
<div class = 'form-group' style="padding:5px;">
<input class = 'form-control' type = "password" name = "password" placeholder = "Password" ngModel>
</div>
<div class = 'form-group' style="padding:5px;">
<input class= 'form-control btn btn-success btn-sm' type = "submit" value = "Login">
</div>
</form>
</div>
</div>
<div class="card-footer text-muted" *ngIf = 'this.isLogin'>

<div class="btn-group" role="group" aria-label="Basic mixed styles example" *ngIf = 'this.isLogin'>
<button type="button" class="btn btn-danger btn-lage" (click) = 'logout()' >logout</button>
</div>

</div>
</div>

auth/components/register/register.component.ts

Créer la component login permettant à un utilisateur de créer un compte

ng g component auth/components/register
import { Component, OnInit } from '@angular/core';
import { ApiService } from './../../../services/api.service'
import { AuthService } from './../../../services/auth.service'
import {NgForm} from '@angular/forms';
import { Router } from '@angular/router';
@Component({
selector: 'app-register',
templateUrl: './register.component.html',
styleUrls: ['./register.component.css']
})
export class RegisterComponent implements OnInit {

isLogin: boolean = false;
errorMessage: any;
constructor(
private _api: ApiService,
private _auth: AuthService,
private _router:Router
) { }

//afin de remplir la liste des roles
listeRoles:any=[];
file:any;
status:number=0;
messageStatus:string="";
ngOnInit() {
this.isUserLogin();
//charger la liste des roles from la table roles
this._api.get('roles/').subscribe(data => {
this.listeRoles=data;
console.log(this.listeRoles);
});

}

selectFile(event: any): void {
this.file = event.target.files[0];
}

//valider l'inscription
onSubmit(form: NgForm) {
const utilisateur=form.value;
const formData: FormData = new FormData();
formData.append("file", this.file);
formData.append("fileName", this.file.name);
formData.append("userInfo", JSON.stringify(utilisateur));
console.log(formData);
this._api.post('utilisateurs/inscription', formData).subscribe((res: any) => {
this.status=res.status;
if (this.status==2) {
this.messageStatus="Votre compte est crée Veuillez attendre la validation par l'admin";
}
else {
console.log(res)
alert(res.msg)
}
});
}

//vérifier si utilisateur infos existe déjà dans localStorage
isUserLogin(){
if(this._auth.getUserDetails() != null){
this.isLogin = true;
}
}
}



auth/components/register/register.component.html


<div class="card text-center ">
<div class="card-header bg-info">
Register
</div>
<div class="card-body">
<h2 *ngIf = 'this.isLogin'>Vous êtes connecté</h2>
<div *ngIf = '!this.isLogin'>
<h3 *ngIf = 'this.status' class="bg-success">{{this.messageStatus}}</h3>
<form #myform = "ngForm" (ngSubmit) = "onSubmit(myform)" *ngIf = '!this.status' >
<div class = 'form-group' style="padding:5px;">
<input class = 'form-control' type = "text" name = "nom" placeholder = "nom" ngModel>
</div>
<div class = 'form-group' style="padding:5px;">
<input class = 'form-control' type = "email" name = "email" placeholder = "Email" ngModel>
</div>
<div class = 'form-group' style="padding:5px;">
<input class = 'form-control' type = "password" name = "password" placeholder = "Password" ngModel>
</div>
<div class = 'form-group' style="padding:5px;">
<select class = 'form-control' name="idRole" ngModel>
<option disabled selected> Sélectionner un Role</option>
<option *ngFor="let role of listeRoles" [ngValue]="role.id">
{{ role.nom }}
</option>
</select>
</div>
<div class = 'form-group' style="padding:5px;">
<input type="file" name="file" class = 'form-control' (change)="selectFile($event)" >
</div>
<div class = 'form-group' style="padding:5px;">
<input class= 'form-control btn btn-success btn-sm' type = "submit" value = "Register">
</div>
</form>
</div>
</div>
</div>

components/profile/profile.component.ts

Créer la component profile pour tester l'authentification

ng g component components/profile
import { Component, OnInit } from '@angular/core';
import { ApiService } from 'src/app/services/api.service';
import { AuthService } from 'src/app/services/auth.service';
@Component({
selector: 'app-profile',
templateUrl: './profile.component.html',
styleUrls: ['./profile.component.css']
})
export class ProfileComponent implements OnInit {
public userinfo: any
constructor(
private _auth:AuthService
) { }
ngOnInit(): void {
//récupérer localStorage pour vérifier s'il est connecté
userinfo= this._auth.getUserDetails()
}
}

auth/components/profile/profile.component.html

<div class="card text-center " *ngIf = 'this.userinfo!=null'>
<div class="card-header bg-info">
Welcome
</div>
<div class="card-body">
<h2>Vous êtes connecté</h2>
</div>
</div>

app.module.ts

import { HTTP_INTERCEPTORS } from '@angular/common/http';
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { RouterModule } from '@angular/router';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { AuthModule } from './auth/auth/auth.module';
import { ProfileComponent } from './components/profile/profile.component';
@NgModule({
declarations: [
AppComponent,
ProfileComponent,
],
imports: [
BrowserModule,
AppRoutingModule,
RouterModule,
AuthModule
],
providers: [ ],
bootstrap: [AppComponent]
})
export class AppModule { }

app.component.html

<nav class="navbar navbar-expand-lg navbar-light bg-light">
<a class="navbar-brand" href="#">Ventes APP</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarNav">
<ul class="navbar-nav">
<li class="nav-item active">
<a class="nav-link" [routerLink] = "['']" routerLinkActive = "active">Home</a>
</li>
<li class="nav-item">
<a class="nav-link" [routerLink] = "['login']" routerLinkActive = "active">Login</a>
</li>
<li class="nav-item">
<a class="nav-link" [routerLink] = "['register']" routerLinkActive = "active" >Register</a>
</li>
</ul>
</div>
</nav>
<router-outlet></router-outlet>

Demarer le backEndProject

backEndProject>node Serveur.js

Demarer le frontEndProjects

frontEndProjects>npm start