Ajout d'un exemple pour les appels http.
This commit is contained in:
@@ -4,12 +4,17 @@ import {PromisesExampleComponent} from "./promises-example/promises-example.comp
|
||||
import {HomeComponent} from "./home/home.component";
|
||||
import {ObservablesExampleComponent} from "./observables-example/observables-example.component";
|
||||
import {StateManagementExampleComponent} from "./state-management-example/state-management-example.component";
|
||||
import {NetworkCallComponent} from "./network-call/network-call.component";
|
||||
|
||||
const routes: Routes = [
|
||||
{
|
||||
path: '',
|
||||
component: HomeComponent
|
||||
},
|
||||
{
|
||||
path: 'network-call',
|
||||
component: NetworkCallComponent
|
||||
},
|
||||
{
|
||||
path: 'promises',
|
||||
component: PromisesExampleComponent
|
||||
|
||||
@@ -12,9 +12,11 @@ import {BackToHomeComponent} from './back-to-home/back-to-home.component';
|
||||
import {MatIconModule} from "@angular/material/icon";
|
||||
import {StateManagementExampleComponent} from './state-management-example/state-management-example.component';
|
||||
import {RestServicesModule} from "./core/rest-services/rest-services.module";
|
||||
import {CarComponent} from './core/components/car/car.component';
|
||||
import {ObservablesExampleModule} from "./observables-example/observables-example.module";
|
||||
import {CoreModule} from "./core/core.module";
|
||||
import {NetworkCallModule} from "./network-call/network-call.module";
|
||||
import {HttpClientInMemoryWebApiModule} from "angular-in-memory-web-api";
|
||||
import {RestApiMockService} from "./core/rest-api-mock/rest-api-mock.service";
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
@@ -33,7 +35,14 @@ import {CoreModule} from "./core/core.module";
|
||||
MatButtonModule,
|
||||
MatIconModule,
|
||||
RestServicesModule,
|
||||
ObservablesExampleModule
|
||||
ObservablesExampleModule,
|
||||
NetworkCallModule,
|
||||
HttpClientInMemoryWebApiModule.forRoot(
|
||||
RestApiMockService,
|
||||
{
|
||||
dataEncapsulation: false
|
||||
}
|
||||
)
|
||||
],
|
||||
providers: [],
|
||||
bootstrap: [AppComponent]
|
||||
|
||||
@@ -3,7 +3,8 @@ import {CommonModule} from '@angular/common';
|
||||
import {CarComponent} from "./components/car/car.component";
|
||||
import {RestServicesModule} from "./rest-services/rest-services.module";
|
||||
import {MaterialModule} from "./material.module";
|
||||
|
||||
import {HttpClientInMemoryWebApiModule} from "angular-in-memory-web-api";
|
||||
import {RestApiMockService} from "./rest-api-mock/rest-api-mock.service";
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
@@ -12,13 +13,13 @@ import {MaterialModule} from "./material.module";
|
||||
imports: [
|
||||
CommonModule,
|
||||
RestServicesModule,
|
||||
MaterialModule
|
||||
MaterialModule,
|
||||
],
|
||||
exports: [
|
||||
CarComponent,
|
||||
RestServicesModule,
|
||||
MaterialModule
|
||||
]
|
||||
],
|
||||
})
|
||||
export class CoreModule {
|
||||
}
|
||||
|
||||
@@ -2,11 +2,15 @@ import {NgModule} from "@angular/core";
|
||||
import {MatIconModule} from "@angular/material/icon";
|
||||
import {MatButtonModule} from "@angular/material/button";
|
||||
import {MatTooltipModule} from "@angular/material/tooltip";
|
||||
import {MatSnackBar, MatSnackBarModule} from "@angular/material/snack-bar";
|
||||
import {MatProgressSpinnerModule} from "@angular/material/progress-spinner";
|
||||
|
||||
const IMPORTED_MATERIAL_MODULES = [
|
||||
MatIconModule,
|
||||
MatButtonModule,
|
||||
MatTooltipModule
|
||||
MatIconModule,
|
||||
MatProgressSpinnerModule,
|
||||
MatSnackBarModule,
|
||||
MatTooltipModule,
|
||||
]
|
||||
|
||||
@NgModule({
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
export interface Car {
|
||||
id: string;
|
||||
id: number;
|
||||
brand: string;
|
||||
model: string;
|
||||
power: number;
|
||||
|
||||
37
src/app/core/rest-api-mock/rest-api-mock.service.ts
Normal file
37
src/app/core/rest-api-mock/rest-api-mock.service.ts
Normal file
@@ -0,0 +1,37 @@
|
||||
import {Injectable} from '@angular/core';
|
||||
import {InMemoryDbService} from "angular-in-memory-web-api";
|
||||
import {Car} from "../model/car";
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class RestApiMockService implements InMemoryDbService {
|
||||
createDb() {
|
||||
const cars: Car[] = [
|
||||
{
|
||||
id: 1,
|
||||
brand: 'Toyota',
|
||||
model: 'Yaris',
|
||||
power: 12,
|
||||
numberOfSeats: 5
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
brand: 'Citroën',
|
||||
model: 'DS',
|
||||
power: 14,
|
||||
numberOfSeats: 5
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
brand: 'Renault',
|
||||
model: 'Twingo',
|
||||
power: 8,
|
||||
numberOfSeats: 2
|
||||
}
|
||||
];
|
||||
return {
|
||||
cars
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@ import { Injectable } from '@angular/core';
|
||||
import {HttpClient} from "@angular/common/http";
|
||||
import {Car} from "../model/car";
|
||||
import {toPromise} from "../utils/promises.utils";
|
||||
import {Observable} from "rxjs";
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
@@ -12,7 +13,11 @@ export class CarRestService {
|
||||
private http: HttpClient
|
||||
) { }
|
||||
|
||||
findById(carId: string): Promise<Car> {
|
||||
return toPromise(this.http.get<Car>(`/cars/${carId}`));
|
||||
findById(carId: number): Promise<Car> {
|
||||
return toPromise(this.findById$(carId));
|
||||
}
|
||||
|
||||
findById$(carId: number): Observable<Car> {
|
||||
return this.http.get<Car>(`/api/cars/${carId}`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,10 @@ export interface Link {
|
||||
}
|
||||
|
||||
const LINKS: Link[] = [{
|
||||
label: 'Les appels réseaux - Promesses ou Observables ?',
|
||||
icon: '🌍',
|
||||
href: '/network-call'
|
||||
}, {
|
||||
label: 'Les promesses',
|
||||
icon: '🙏',
|
||||
href: '/promises'
|
||||
|
||||
20
src/app/network-call/network-call.component.html
Normal file
20
src/app/network-call/network-call.component.html
Normal file
@@ -0,0 +1,20 @@
|
||||
<div class="component">
|
||||
<h1>Les appels réseaux - Promesses ou Observables ?</h1>
|
||||
<div class="actions">
|
||||
<button mat-raised-button
|
||||
(click)="loadCar()"
|
||||
[disabled]="isLoading$ | async">
|
||||
Load the car
|
||||
</button>
|
||||
</div>
|
||||
<div class="loading" *ngIf="isLoading$ | async">
|
||||
<h2>Loading...</h2>
|
||||
<mat-spinner></mat-spinner>
|
||||
</div>
|
||||
<ng-container *ngIf="isLoaded">
|
||||
<h2>Car data</h2>
|
||||
<div class="centered">
|
||||
<app-car [value]="car"></app-car>
|
||||
</div>
|
||||
</ng-container>
|
||||
</div>
|
||||
7
src/app/network-call/network-call.component.scss
Normal file
7
src/app/network-call/network-call.component.scss
Normal file
@@ -0,0 +1,7 @@
|
||||
.component {
|
||||
.loading {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
76
src/app/network-call/network-call.component.ts
Normal file
76
src/app/network-call/network-call.component.ts
Normal file
@@ -0,0 +1,76 @@
|
||||
import {Component} from '@angular/core';
|
||||
import {BehaviorSubject, catchError, EMPTY, finalize, Observable, tap} from "rxjs";
|
||||
import {Car} from "../core/model/car";
|
||||
import {CarRestService} from "../core/rest-services/car.rest-service";
|
||||
import {MatSnackBar} from "@angular/material/snack-bar";
|
||||
|
||||
const CAR_ID = 1;
|
||||
|
||||
@Component({
|
||||
selector: 'app-network-call',
|
||||
templateUrl: './network-call.component.html',
|
||||
styleUrls: ['./network-call.component.scss']
|
||||
})
|
||||
export class NetworkCallComponent {
|
||||
private isLoadingSubject: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);
|
||||
isLoaded: boolean = false;
|
||||
car?: Car;
|
||||
|
||||
constructor(
|
||||
private carRestService: CarRestService,
|
||||
private snackBar: MatSnackBar
|
||||
) {
|
||||
}
|
||||
|
||||
get isLoading$(): Observable<boolean> {
|
||||
return this.isLoadingSubject.asObservable();
|
||||
}
|
||||
|
||||
loadCar(): void {
|
||||
this.loadThroughAPromise();
|
||||
// this.loadThroughAnObservable();
|
||||
}
|
||||
|
||||
private loadThroughAPromise(): void {
|
||||
this.isLoadingSubject.next(true);
|
||||
this.isLoaded = false;
|
||||
|
||||
this.carRestService.findById(CAR_ID)
|
||||
.then(car => {
|
||||
this.car = car;
|
||||
this.isLoaded = true;
|
||||
})
|
||||
.catch(error => {
|
||||
console.log('An error occured while loading the car.', error);
|
||||
this.snackBar.open(
|
||||
'An error occured while loading the car.',
|
||||
'Close',
|
||||
{duration: 2000}
|
||||
);
|
||||
})
|
||||
.finally(() => this.isLoadingSubject.next(false));
|
||||
}
|
||||
|
||||
private loadThroughAnObservable(): void {
|
||||
this.isLoadingSubject.next(true);
|
||||
this.isLoaded = false;
|
||||
|
||||
this.carRestService.findById$(CAR_ID)
|
||||
.pipe(
|
||||
tap(car => {
|
||||
this.car = car;
|
||||
this.isLoaded = true;
|
||||
}),
|
||||
catchError(error => {
|
||||
console.log('An error occured while loading the car.', error);
|
||||
this.snackBar.open(
|
||||
'An error occured while loading the car.',
|
||||
'Close',
|
||||
{duration: 2000}
|
||||
);
|
||||
return EMPTY;
|
||||
}),
|
||||
finalize(() => this.isLoadingSubject.next(false))
|
||||
).subscribe();
|
||||
}
|
||||
}
|
||||
21
src/app/network-call/network-call.module.ts
Normal file
21
src/app/network-call/network-call.module.ts
Normal file
@@ -0,0 +1,21 @@
|
||||
import {NgModule} from '@angular/core';
|
||||
import {CommonModule} from '@angular/common';
|
||||
import {NetworkCallComponent} from "./network-call.component";
|
||||
import {CoreModule} from "../core/core.module";
|
||||
import {HttpClientModule} from "@angular/common/http";
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
NetworkCallComponent
|
||||
],
|
||||
imports: [
|
||||
CommonModule,
|
||||
CoreModule,
|
||||
HttpClientModule
|
||||
],
|
||||
exports: [
|
||||
NetworkCallComponent
|
||||
]
|
||||
})
|
||||
export class NetworkCallModule {
|
||||
}
|
||||
@@ -6,5 +6,10 @@ import { Component } from '@angular/core';
|
||||
styleUrls: ['./observables-example.component.scss']
|
||||
})
|
||||
export class ObservablesExampleComponent {
|
||||
/*
|
||||
Formulaires :
|
||||
-> valueChanges / debounceTime etc...
|
||||
Appel réseau -> pour voir la diff avec les promesses
|
||||
|
||||
*/
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ export class SimpleObservableExempleComponent {
|
||||
|
||||
addNewCar(): void {
|
||||
const newCar: Car = {
|
||||
id: `${Math.random() * 100}`,
|
||||
id: Math.random() * 100,
|
||||
brand: 'Toyota',
|
||||
model: 'Yaris',
|
||||
power: 12,
|
||||
|
||||
@@ -8,10 +8,17 @@ import {Car} from "../core/model/car";
|
||||
})
|
||||
export class PromisesExampleComponent {
|
||||
car?: Car = {
|
||||
id: '1234567890',
|
||||
id: 1,
|
||||
brand: 'Toyota',
|
||||
model: 'Yaris',
|
||||
power: 12,
|
||||
numberOfSeats: 5
|
||||
};
|
||||
|
||||
/*
|
||||
// Async / Await -> + comparaison avec les then
|
||||
// new Promise "à la main"
|
||||
// les then chaînés
|
||||
// catch (avec 1 ou plusieurs then) -> try/catch avec un await
|
||||
*/
|
||||
}
|
||||
|
||||
@@ -2,3 +2,9 @@
|
||||
|
||||
html, body { height: 100%; }
|
||||
body { margin: 0; font-family: Roboto, "Helvetica Neue", sans-serif; }
|
||||
|
||||
.centered {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
}
|
||||
Reference in New Issue
Block a user