I want to calculate the sum of the ShoppingCart at Firebase with Angularfire2

◇◆丶佛笑我妖孽 提交于 2019-12-02 22:13:31

问题


I'm building an experimental application that uses Angular2, Firebase and AngularFire2. This is what my data looks like:

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

Below are my cart.ts

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

Below are my cart.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>

I want to calculate the sum of the ShoppingCart. So I want to find the value of (2*5) + (1*6) = 16 as the data shows. How do i do it.

This plunker


回答1:


The problem is in this 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);
});

Two calls: carts.map and carts.forEach are synchronous and happen one after another. But loading of products (via af.database.object) is asynchronous so when you iterating over cartItem products not been loaded yet.

The solution would be to chain product loading and total calculation. See here.




回答2:


Since you are using Firebase, first thing I notice is key names. Fix them like this. Where cart.$key is some hashcode e.g. -KXeML1Na9qCsvK4JSyQ.

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

Now rewrite your frontend logic. Please write and export suitable Product class as well. Put below inside 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));
}

NOW, do your final calculations either in Product class or subscribe. Below would go inside DisplayCart.component.ts

items;
constructor(private shoppingCartService: ShoppingCartService){}

ngOnInit(){
  const items$ = this.shoppingCartService.findAllProductsForCart(this.cartId);

 items$.subscribe(items => this.items = items);
}

You still need to complete the remaining stuff on your own, good luck.



来源:https://stackoverflow.com/questions/40833704/i-want-to-calculate-the-sum-of-the-shoppingcart-at-firebase-with-angularfire2

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!