as title says have a problem with displaying price and quantity. Here's what I did so far:
shopping-cart-item
export class ShoppingCartItem {
id?: string;
name: string;
imgCover: string;
price: number;
quantity: number;
}
shopping-cart.service
async getCart(): Promise<Observable<ShoppingCartItem[]>> {
let cartId = await this.getOrCreateCartId();
let cartCollection = this.afs.collection(`shopping-carts/${cartId}/items`, ref => ref.where('id','==', cartId));
return cartCollection.snapshotChanges().pipe(map( actions => {
return actions.map(a => {
const data = a.payload.doc.data() as ShoppingCartItem;
const id = a.payload.doc.id;
return { id, ...data };
});
})
);
}
navbar.component
totalCart$: Observable<ShoppingCartItem[]>;
items: ShoppingCartItem[]
total: number = 0;
constructor(
public dialog: MatDialog,
private shoppingCartService: ShoppingCartService,
) {}
ngOnInit() {
this.getCart();
}
async getCart() {
this.totalCart$ = await this.shoppingCartService.getCart();
this.totalCart$.subscribe(data => {
data.forEach(element => {
this.total += element.quantity
console.log(this.total);
})
})
}
With this approach I can display correct data on first load, after that quantity is doubled by same amount + 1 (because calling existing data again). How to merge quantity and price fields?
UPDATE:
shopping-cart-item
export class ShoppingCartItem {
id?: string;
name: string;
imgCover: string;
price: number;
quantity: number;
constructor(param?: Partial<ShoppingCartItem>) {
Object.assign(this, param);
}
}
product-card.component
items: ShoppingCartItem[];
constructor(
public adminProductService: AdminProductService,
private shoppingCartService: ShoppingCartService
) {}
ngOnInit() {
this.getProducts();
this.getCart()
}
async getQuantity(product: Product) {
let itemsMap: { [productId: string]: ShoppingCartItem};
itemsMap = itemsMap || {};
for (let productId in itemsMap) {
let item = itemsMap[productId];
this.items.push(new ShoppingCartItem ({
...item,
id: productId,
}));
}
let item = itemsMap[product.id];
console.log(item.quantity);
return item ? item.quantity : 0;
}
in html:
<div>{{ getQuantity(product)}} in Cart</div>
and getting the following error:
Can't resolve all parameters for ShoppingCartItem: (?)..
UPDATE 2
getQuantity(product: Product) {
let itemsMap: { [productId: string]: ShoppingCartItem}
itemsMap = itemsMap || {}; //<--- this returns Cannot read property 'quantity' of undefined but when I comment out it returns ID of clicked item Cannot read property '592HNZP1z5KNFqHf2Pl5' of undefined
for (let productId in itemsMap) {
let item = itemsMap[productId];
this.items.push(new ShoppingCartItem({
...item,
id: productId,
}));
}
let item = itemsMap[product.id];
console.log(item.quantity);
return item ? item.quantity : 0;
}
To prevent the totals from doubling on subsequent calls, just add a local variable to add up your quantities and prices to. Once you finish adding the prices and quantities up you can assign them the actual class fields, see example below:
totalCart$: Observable<ShoppingCartItem[]>;
items: ShoppingCartItem[]
totalQuantity: number = 0;
totalPrice: number = 0;
constructor(
public dialog: MatDialog,
private shoppingCartService: ShoppingCartService,
) { }
ngOnInit() {
this.getCart();
}
async getCart() {
this.totalCart$ = await this.shoppingCartService.getCart();
this.totalCart$.subscribe(data => {
let totalQuantity = 0;
let totalPrice = 0;
data.forEach(element => {
totalQuantity += element.quantity
totalPrice += element.quantity * element.price
console.log(totalQuantity, totalPrice);
})
this.totalQuantity = totalQuantity;
this.totalPrice = totalPrice;
})
}