1

I have the following code and I'm trying to calculate the total of all items added to the cart. When I use reduce I don't get back anything but while troubleshooting I added a map in there (commented out code) and that prints a value. I can add more code here but so you know everything is working fine. I am able to see data in the cart which is an array of objects. I just need to iterate over and calculate the total price. Please advise.

this.store.select('cart').pipe(reduce((accumalatedTotal, cartItem) => accumalatedTotal + (cartItem.price), 0))subscribe((val:number) => console.log("===>>>", val));

//this.store.select('cart').pipe(map(cartItem => cartItem.price)).subscribe((val:number) => console.log("===>>>", val));

With that commented out map I can print the item price but I cannot see anything with reduce.

sayayin
  • 971
  • 5
  • 23
  • 36

3 Answers3

0

try like this

this.store.select('cart').pipe(reduce((accumalatedTotal, cartItem) => accumalatedTotal += (cartItem.price), 0)).subscribe((val:number) => console.log("===>>>", val));

i suggest you to create a custom selector like:

export const getCartProductsTotalPrice = createSelector(
selectShoppingCartState,(state: CartState) => {
return state.cart.reduce((total, current, idx) => total += current.prodotto.price, 0)
;});

and in the component.ts simply call return this.store.pipe(select(getCartProductsTotalPrice));

majkl zumberi
  • 156
  • 1
  • 8
0

use the map operator and the reduce function on array to get the total.

this.store.select('cart').pipe( 
  map(cart => cart.reduce((accumalatedTotal, cartItem) => 
    accumalatedTotal + (cartItem.price * cartItem.quantity), 0)
  )
).subscribe((val:number) => console.log("===>>>", val))

The Reduce operator applies a function to the first item emitted by the source Observable and then feeds the result of the function back into the function along with the second item emitted by the source Observable, continuing this process until the source Observable emits its final item and completes, whereupon the Observable returned from Reduce emits the final value returned from the function.

The reduce operator will be useful if you the value of cart is a stream of items. In your case you are only selecting the 'cart' from the store i.e. one array item.

Breakdown of the code

this.store.select('cart').pipe( 

)

This select value of the Cart from your store say

[
  {id: 1, price: 100},
  {id: 2, price: 50},
  ...etc
]

The map operator provides the cart variable to the function

cart => cart.reduce(
  (accumalatedTotal, {price, quantity}) => 
    accumalatedTotal + (price * quantity), 0)) )

The above calculates the sum of the price in the cart

Owen Kelvin
  • 14,054
  • 10
  • 41
  • 74
  • Thanks for the reply. I'm trying this out and also trying to make sense of it. Where will the cart value come from within map here, it is not recognized: cart.reduce((accumalatedTotal, currentPrice) – sayayin Sep 05 '20 at 16:17
  • `import { map } from 'rxjs/operators'; – Owen Kelvin Sep 05 '20 at 16:20
  • And just so we are clear. My cart is an array of objects. Each item object looks like this: { id: 1, name: 'Burgundy T-shirt', imageUrl: './assets/img/polka-dot-shirt.png', price: 25, quantity: 1 } And yes I have map imported. Thanks – sayayin Sep 05 '20 at 16:23
  • Just making a few changes – Owen Kelvin Sep 05 '20 at 16:25
  • Thank you so much for such detailed explanation. I got this working with your help with a slight change. The second parameter of reduce needs to be the item of array we are iterating over. So the code that worked for me is the following. Can you please update the answer with this change and I will accept it? Thanks again this.store.select('cart').pipe( map(cart => cart.reduce((accumalatedTotal, cartItem) => accumalatedTotal + (cartItem.price * cartItem.quantity), 0)) ).subscribe((val:number) => console.log("===>>>", val)); – sayayin Sep 05 '20 at 16:44
-1

In my guess, there's two possibilities. One is typo, and second is not completed Observable. The reduce operator shows result when the Observable is completed.

toyseed
  • 99
  • 6