Je veux calculer la somme du ShoppingCart sur Firebase avec Angularfire2

Je développe une application expérimentale qui utilise Angular2, Firebase et AngularFire2. Voici à quoi ressemblent mes données:

{ "ShoppingCartItem": { "item1":{ "quantity": 2, "productId": "abc" }, "item2":{ "quantity": 1, "productId": "bcd" } } "Product" { "abc":{ "name": "product1", "price": 5 }, "bcd":{ "name": "product2", "price": 6 } } } 

Voici mon panier.

 this.items = this.af.database.list('ShoppingCartItem') .map(carts => { return carts.map(item => { item.product = this.af.database.object(`Product/${item.productId}`); return item; }); }); 

Voici mon panier.html

 <table> <tbody> <tr *ngFor="let item of (items | async)"> <td>{{(item.product | async)?.name}}</td> <td><input type="text" name="quantity" [(ngModel)]="item.quantity" size="1" class="form-control"></td> <td>{{(item.product | async)?.price | number: '.2'}}</td> <td>{{(item.product | async)?.price * item.quantity | number: '.2'}}</td> </tr> </tbody> <tfoot> <tr> <td colspan="2" class="text-right"> <strong>Total :</strong> </td> <td colspan="2" class="text-left"> ????????? </td> </tr> </tfoot> 

Je veux calculer la somme du ShoppingCart. Je souhaite donc trouver la valeur de (2 * 5) + (1 * 6) = 16 comme le montrent les données. Comment fait-on ça.

Ce plunker

Le problème est dans ce code:

 carts.map(cart => { this.af.database.object(`Product/${cart.productId}`) .subscribe(d => { cart.product = d; }); return cart; }); carts.forEach(cartItem => { qty += cartItem.quantity; total += cartItem.quantity * cartItem.product.price; // console.log(cartItem); }); 

Deux appels: carts.map et carts.forEach est synchrone et se produit l'un après l'autre. Mais le chargement des produits (via af.database.object ) est asynchrone, alors lorsque vous faites itérer sur les produits cartItem non encore chargés.

La solution serait de raccorder le chargement du produit et le calcul total. Voyez ici .

Puisque vous utilisez Firebase, je remarque d'abord les noms clés. Réparez-les comme ça. Lorsque le cart.$key est un code hash par exemple -KXeML1Na9qCsvK4JSyQ .

 { "ShoppingCartItem": { -KXeML1OkDyUVTAdHYPx : { -KXeML1OkDyUVTAdHYPx: true, -KXeML1PP4faQG2Z3fzU: true }, -KXeML1Na9qCsvK4JSyQ: { -KXeML1PP4faQG2Z3fzU: true } }, "Products": { -KXeML1OkDyUVTAdHYPx:{ "name": "product1", "price": 5 }, -KXeML1PP4faQG2Z3fzU:{ "name": "product2", "price": 6 } } } 

Réérez maintenant votre logique frontend. Veuillez également écrire et exporter une classe de Product appropriée. Mettez ci-dessous dans le shoppingcart.service.ts

 findProductKeysForCart(cartId: string): Observable<string[]> { return this.database.list('ShoppingCartItem', { query: { orderByKey: true, equalTo: cartId } }) //.do(console.log)// Check whats coming, //.map(result => result[0])// might be needed .map(sci => sci.map(product => product.$key)); } findProductsForProductKeys(productKeys$: Observable<string[]>): Observable<Product[]> { return productKeys$ .map(productKeys => productKeys.map(productKey => this.database.object(`Products/${productKey}`))) .flatMap(prodObservables => Observable.combineLatest(prodObservables)); } findAllProductsForCart(cartId): Observable<Product[]> { //this fn gets your Products for a cart return this.findProductsForProductKeys(this.findProductKeysForCart(cartId)); } 

MAINTENANT, effectuez vos calculs finaux soit dans la classe de produit ou inscrivez-vous. Ci-dessous irait à l'intérieur de DisplayCart.component.ts

 items; constructor(private shoppingCartService: ShoppingCartService){} ngOnInit(){ const items$ = this.shoppingCartService.findAllProductsForCart(this.cartId); items$.subscribe(items => this.items = items); } 

Vous devez toujours compléter les autres choses par vous-même, bonne chance.