Bonjour,
je développe une appli de gestion de produits sur angular 6 et spring boot 2.
J'ai créé mon service qui appelle la liste de mes produits côté angular et côté spring boot le contrôleur associé avec l'annotation cross origin pour permettre mon front d'atteindre mon back.
Malheureusement , quand je tape l'url : http://localhost:4200/produit, j'ai une erreur sur la console de mon navigateur : chrome, firefox, safari :
Error: Uncaught (in promise): HttpErrorResponse: {"headers":{"normalizedNames":{},"lazyUpdate":null,"headers":{}},"status":0,"statusText":"Unknown Error","url":null,"ok":false,"name":"HttpErrorResponse","message":"Http failure response for (unknown url): 0 Unknown Error","error":{"isTrusted":true}}
at resolvePromise (zone.js:831)
at resolvePromise (zone.js:788)
voici mon service côté angular :
Code js : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 export const API_URLS = { PRODUITS_URLS : 'http://localhost:8080/api/produit' }
Code js : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36 import { Injectable } from "@angular/core"; import { HttpClient, HttpHeaders } from "@angular/common/http"; import { Observable } from "rxjs"; import { API_URLS } from '../config/api.url.config'; import { Produit } from "../shared/produit"; const httpOptions = { headers: new HttpHeaders({ 'Content-Type': 'application/json' }) }; @Injectable() export class ProduitService { constructor(private http : HttpClient) { } getPoduits():Observable<any>{ /*return this.http.get(API_URLS.PRODUITS_URLS);*/ return this.http.get('/api/produit'); } addProduit(produit : Produit):Observable<any>{ return this.http.post('/api/produit',produit); } updateProduit(produit : Produit):Observable<any>{ /*return this.http.put(API_URLS.PRODUITS_URLS,produit);*/ return this.http.put('/api/produit',produit); } deleteProduit(id : number):Observable<any>{ return this.http.delete(`/api/produit/${id}`); } }
Code js : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85 import { Component, OnInit } from '@angular/core'; import { Produit } from '../shared/produit'; import { FormGroup, FormBuilder, Validators } from '@angular/forms'; import { ProduitService } from './produit.service'; import { ActivatedRoute } from '@angular/router'; @Component({ selector: 'app-produit', templateUrl: './produit.component.html', styleUrls: ['./produit.component.css'] }) export class ProduitComponent implements OnInit { produitForm : FormGroup; products:Produit[]; operation : string = 'add'; selectedProduit : Produit; constructor(private produitService:ProduitService, private fb : FormBuilder, private route : ActivatedRoute) { this.createForm(); } ngOnInit() { /*this.products = this.produitService.getPoduits();*/ this.initProduit(); // this.loadProduits(); this.products = this.route.snapshot.data.produits; } createForm(){ this.produitForm = this.fb.group({ ref:['', Validators.required], quantite:'', prixUnitaire:'' }); } loadProduits() { this.produitService.getPoduits().subscribe( data => { this.products = data}, error => { console.log("An error was occured.")}, () => { console.log("loading products")} ) } addProduit(){ const p = this.produitForm.value; console.log("produit envoye "); console.log(p); this.produitService.addProduit(p).subscribe( res => { this.initProduit(); this.loadProduits(); } ); } updateProduit(){ this.produitService.updateProduit(this.selectedProduit).subscribe( res => { this.initProduit(); this.loadProduits(); } ); } initProduit(){ this.selectedProduit = new Produit(); this.createForm(); } deleteProduit(){ this.produitService.deleteProduit(this.selectedProduit.id).subscribe( res => { this.loadProduits(); } ); } }
Code HTML : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83 <!-- <h3>Hello produits</h3> <ul > <li *ngFor="let product of products"> Ref : {{product.ref}} Quantité : {{product.quantite}} Prix unitaire : {{product.prixUnitaire}} </li> </ul> --> <h3>Produits</h3> <div class="container"> <div class="row"> <div class="col-lg-7"> <table class="table table-hover"> <thead> <tr> <th>Référence</th> <th>Quantité</th> <th>Prix Unitaire</th> <th><button class="btn btn-outlet-primary" (click)="operation = 'add';initProduit();">ADD</button></th> </tr> </thead> <tbody> <tr *ngFor="let produit of products"> <td>{{produit.ref}}</td> <td>{{produit.quantite}}</td> <td>{{produit.prixUnitaire}}</td> <td><button class="btn btn-outlet-primary" (click)="operation = 'edit'; selectedProduit = produit">Edit</button></td> <td><button class="btn btn-outlet-danger" (click)="operation = 'remove'; selectedProduit = produit">Remove</button></td> </tr> </tbody> </table> </div> <div class="col-lg-5"> <div class="card"> <div class="card-header bg-info text-white"> {{operation == 'add' ? 'Ajouter produit': operation == 'edit' ? 'Modifier produit': operation == 'remove' ? 'Supprimer produit':''}} </div> <div class="card-body"> <div *ngIf="operation == 'add' || operation == 'edit'"> <form [formGroup]="produitForm"> <div class="form-group"> <label>Réference : </label> <input type="text" class="form-control" formControlName="ref" [(ngModel)]="selectedProduit.ref" /> </div> <div class="alert alert-danger" *ngIf="produitForm.controls['ref'].invalid && (produitForm.controls['ref'].dirty || produitForm.controls['ref'].touched)"> Réference est obligatoire ! </div> <div class="form-group"> <label>Quantité : </label> <input type="number" class="form-control" formControlName="quantite" [(ngModel)]="selectedProduit.quantite" /> </div> <div class="form-group"> <label>Prix unitaire : </label> <input type="number" class="form-control" formControlName="prixUnitaire" [(ngModel)]="selectedProduit.prixUnitaire" /> </div> <button class="btn btn-success" (click)="operation == 'add' ? addProduit() : updateProduit()" [disabled]="(produitForm.prestine || produitForm.invalid)"> {{operation == 'add' ? 'Ajouter' : operation == 'edit' ? 'Modifier' : ''}}</button> </form> </div> <div *ngIf="operation == 'remove'"> <p class="card-title">Réference : {{selectedProduit.ref}}</p> <p class="card-title">Voulez-vous supprimer ce produit ?</p> <button class="btn btn-success" [disabled]="!selectedProduit.ref" (click)="deleteProduit()">Confirmez</button> </div> </div> <div class="card-footer"> </div> </div> </div> </div> </div>
Code js : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40 import { NgModule } from '@angular/core'; import { RouterModule, Routes } from '@angular/router'; import { ProduitComponent } from './produit/produit.component'; import { DashboardComponent } from './dashboard/dashboard.component'; import { ProduitResolver } from './produit/produit.resolver'; export const appRoutes : Routes = [ { path:'produit', component:ProduitComponent, resolve:{ produits : ProduitResolver } }, { path:'dashboard', component:DashboardComponent }, { path:'', redirectTo:'/dashboard', pathMatch:'full' } ] @NgModule({ imports : [ RouterModule.forRoot( appRoutes, {enableTracing:true} ) ], exports : [RouterModule], providers : [ProduitResolver] }) export class AppRoutingModule { }
Code js : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 import { Injectable } from "@angular/core"; import { Resolve } from "@angular/router"; import { ProduitService } from "./produit.service"; @Injectable() export class ProduitResolver implements Resolve<any> { constructor(private produitService : ProduitService) { } resolve() { return this.produitService.getPoduits(); } }
Code JSON : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52 { "name": "gestion-stock", "version": "0.0.0", "scripts": { "ng": "ng", "start": "ng serve --proxy-config proxy.conf.json", "build": "ng build", "test": "ng test", "lint": "ng lint", "e2e": "ng e2e" }, "private": true, "dependencies": { "@angular/animations": "^6.1.0", "@angular/common": "^6.1.0", "@angular/compiler": "^6.1.0", "@angular/core": "^6.1.0", "@angular/forms": "^6.1.0", "@angular/http": "^6.1.0", "@angular/platform-browser": "^6.1.0", "@angular/platform-browser-dynamic": "^6.1.0", "@angular/router": "^6.1.0", "core-js": "^2.5.4", "rxjs": "~6.2.0", "zone.js": "~0.8.26", "bootstrap": "^4.0.0-beta", "font-awesome": "^4.7.0", "jquery": "^3.2.1", "popper.js": "^1.12.5" }, "devDependencies": { "@angular-devkit/build-angular": "~0.8.0", "@angular/cli": "~6.2.5", "@angular/compiler-cli": "^7.2.5", "@angular/language-service": "^6.1.0", "@types/jasmine": "~2.8.8", "@types/jasminewd2": "~2.0.3", "@types/node": "~8.9.4", "codelyzer": "~4.3.0", "jasmine-core": "~2.99.1", "jasmine-spec-reporter": "~4.2.1", "karma": "^4.0.0", "karma-chrome-launcher": "~2.2.0", "karma-coverage-istanbul-reporter": "~2.0.1", "karma-jasmine": "~1.1.2", "karma-jasmine-html-reporter": "^0.2.2", "protractor": "~5.4.0", "ts-node": "~7.0.0", "tslint": "~5.11.0", "typescript": "~3.1.1" } }
et côté back end : java spring boot 2
Code Java : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46 package com.gestion.stock.controller; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.CrossOrigin; import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import com.gestion.stock.entity.Produit; import com.gestion.stock.service.IProduitService; @RestController @RequestMapping("/api/produit") //@CrossOrigin @CrossOrigin(origins = "http://localhost:4200") public class ProduitController { @Autowired private IProduitService produitService; @GetMapping public List<Produit> getProduits() { return produitService.getProduits(); } @PostMapping public void addProduit(@RequestBody Produit produit) { produitService.addProduit(produit); } @PutMapping public void updateProduit(@RequestBody Produit produit) { produitService.updateProduit(produit); } @DeleteMapping("{/id}") public void deletedProduit(@PathVariable Long id) { produitService.deleteProduit(id); } }
je n'arrive pas à trouver la solution après multiple recherche sur le net.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4spring.jpa.hibernate.ddl-auto=create spring.datasource.url=jdbc:mysql://localhost:3306/stock_produits?zeroDateTimeBehavior=CONVERT_TO_NULL&serverTimezone=UTC spring.datasource.username=root spring.datasource.password=root
Partager