diff --git a/src/app/rxjs-app/app/components/fruits-list.component.ts b/src/app/rxjs-app/app/components/fruits-list.component.ts index 0b0ff12..a02e65a 100644 --- a/src/app/rxjs-app/app/components/fruits-list.component.ts +++ b/src/app/rxjs-app/app/components/fruits-list.component.ts @@ -5,10 +5,13 @@ import { CartService } from '../../shared/services/cart.service'; @Component({ selector: 'app-fruits-list', template: ` -
+
{{fruit.name}} - {{fruit.price}}€
+ + {{cartService.total$ | async}} + `, styles: ``, changeDetection: ChangeDetectionStrategy.OnPush diff --git a/src/app/rxjs-app/shared/services/cart.service.ts b/src/app/rxjs-app/shared/services/cart.service.ts index bec75fa..031ab2e 100644 --- a/src/app/rxjs-app/shared/services/cart.service.ts +++ b/src/app/rxjs-app/shared/services/cart.service.ts @@ -1,6 +1,6 @@ import { Injectable } from '@angular/core'; import { Fruit, FruitState } from '../model/fruit'; -import { BehaviorSubject, Observable, map } from 'rxjs'; +import { BehaviorSubject, Observable, Subject, map } from 'rxjs'; @Injectable({ providedIn: 'root' @@ -27,14 +27,31 @@ export class CartService { /* Pour ceux qui veulent aller plus loin : - Implémenter un observable total$, qui renvoie le prix total du panier */ + private _total: BehaviorSubject; total$!: Observable + addFruit(fruit: Fruit) { /* Ajoute un fruit dans le panier /* Deux cas à considerer : - Le fruit n'est pas déja dans le panier - Le fruit est déja dans le panier */ + let fruitValue = this._cart.getValue() + + if (fruitValue.has(fruit.id)) { + const fruitStateIncart = fruitValue.get(fruit.id); + let fruitQuantityInCart = fruitStateIncart?.quantity; + + if (fruitStateIncart && fruitQuantityInCart) { + fruitQuantityInCart++; + fruitValue.set(fruit.id, {...fruit, quantity: fruitQuantityInCart}); + } + } else { + fruitValue.set(fruit.id, {...fruit, quantity: 1}); + } + this._cart.next(fruitValue); + this._total.next(this.calculTotalPrice(fruitValue)); } /* /!\ Pour les méthodes addFruit(), removeFruit() et removeAllFruitOfType(), attention à ne pas muter la Map existante */ @@ -45,20 +62,56 @@ export class CartService { - Il reste un fruit de ce type dans le panier, enlever l'entrée dans la map - Il reste plusieurs fruits de ce type dans le panier, dans ce cas enlever tous les types de fruits */ + + let fruitValue = this._cart.getValue(); + + if (fruitValue.has(fruit.id)) { + const fruitStateInCart = fruitValue.get(fruit.id); + let fruitQuantityInCart = fruitStateInCart?.quantity; + + if (fruitStateInCart && fruitQuantityInCart && fruitQuantityInCart > 1) { + fruitQuantityInCart--; + fruitValue.set(fruit.id, {...fruit, quantity : fruitQuantityInCart}); + } else { + fruitValue.delete(fruit.id); + } + } + + this._cart.next(fruitValue); + this._total.next(this.calculTotalPrice(fruitValue)) } removeAllFruitOfType(fruit: Fruit) { /* Enlève tous les fruits d'un type dans le panier */ + let fruitValue = this._cart.getValue(); + fruitValue.delete(fruit.id); + + this._cart.next(fruitValue); + this._total.next(this.calculTotalPrice(fruitValue)); } + + /* Ici le constructeur nous donne une valeur par défaut pour le panier, mais il n'est pas indispensable */ constructor() { const defaultMap = new Map() defaultMap.set(1, { id: 1, name: "Pomme", price: 1, quantity: 5 }) defaultMap.set(2, { id: 2, name: "Orange", price: 3, quantity: 10 }) + // defaultMap.set(3, { id: 3, name: "Hasbulla", price: 999, quantity: 1 }) + const defaultPrice = this.calculTotalPrice(defaultMap) + this._cart = new BehaviorSubject(defaultMap) this.cart$ = this._cart.asObservable() - } + this._total = new BehaviorSubject(defaultPrice); + this.total$ = this._total.asObservable(); + } + + calculTotalPrice(cartFruit: Map): number { + let count = 0; + cartFruit.forEach((fruit) => count+= fruit.price * fruit.quantity) + return count; + } + } diff --git a/src/app/rxjs-app/shared/services/fruits.service.ts b/src/app/rxjs-app/shared/services/fruits.service.ts index 7fb07cf..b2eb77e 100644 --- a/src/app/rxjs-app/shared/services/fruits.service.ts +++ b/src/app/rxjs-app/shared/services/fruits.service.ts @@ -1,5 +1,6 @@ -import { Injectable } from '@angular/core'; +import { Injectable, inject } from '@angular/core'; import { Fruit } from '../model/fruit'; +import { HttpClient } from '@angular/common/http'; @Injectable({ providedIn: 'root' @@ -11,9 +12,15 @@ export class FruitService { } /* Remplacer cette liste par un appel http */ - private readonly _list: Fruit[] = [ - { id: 1, name: "Pomme", price: 1 }, - { id: 2, name: "Orange", price: 3 }, - ] + // private readonly _list: Fruit[] = [ + // { id: 1, name: "Pomme", price: 1 }, + // { id: 2, name: "Orange", price: 3 }, + // ] + + readonly FRUIT_DB = "http://localhost:3000/fruits" + _http = inject(HttpClient); + + private readonly _list = this._http.get(this.FRUIT_DB) + }