Home > database >  using forEach() to find price of items in cat in the backend
using forEach() to find price of items in cat in the backend

Time:06-22

I'm trying to implement a payment gateway system into a project that I'm working on, and I need to get the cart total in the backend instead of just in the frontend. I'm trying to do this with forEach() and reduce(). The part that I am struggling with is filtering through _ids from all of my products to then find the _ids associated with my items in my cart (cartInfo), and then from there getting the price of the items whose _ids match the _ids of the items in the cart. Below, I have included what I have so far. I would really appreciate any help or guidance on how to do this. Thank you!

const total = products.forEach(x => {
    if (x._id === cartInfo._id) {
      const itemsTotal = x.price * cartInfo.qty
      }
    })
  
const sum = itemsTotal.reduce((a, b) => a   b, 0)

products is an array of all of the products and cartInfo contains the _ids and qtys of each of the products in the cart.

Example of cartInfo:

0: {_id: '624bc7fe0f91078261ab6529', qty: 1}
1: {_id: '624bc8240f91078261ab6531', qty: 2}

Example of products:

0: {_id: '624bc7fe0f91078261ab6529', name: sample 1, price: 30, countInStock: 10}
1: {_id: '624bc8240f91078261ab6531', name: sample 2, price 10, countInStock: 4}
2: {_id: '624bc1a50f91078261ab650d', name: sample 3, price 15, countInStock: 1}
3: {_id: '62562017645f1882e45adc32', name: sample 4, price 20, countInStock: 7}

CodePudding user response:

For readability and loop optimisation, I prefer the simple for...of statement for these kinds of scenarios:

let cartInfo = [
  {
    _id: `624bc7fe0f91078261ab6529`,
    qty: 1
  },
  {
    _id: `624bc8240f91078261ab6531`,
    qty: 2
  },
];

let products = [
  {
    _id: `624bc7fe0f91078261ab6529`,
    name: `sample 1`,
    price: 30,
    countInStock: 10
  },
  {
    _id: `624bc8240f91078261ab6531`,
    name: `sample 2`,
    price: 10,
    countInStock: 4
  },
  {
    _id: `624bc1a50f91078261ab650d`,
    name: `sample 3`,
    price: 15,
    countInStock: 1
  },
  {
    _id: `62562017645f1882e45adc32`,
    name: `sample 4`,
    price: 20,
    countInStock: 7
  },
];

let cartTotalPrice = 0;

for (cartItem of cartInfo) {
  for (product of products) {
    if (cartItem._id === product._id) {
      cartTotalPrice  = (product.price * cartItem.qty);
      break;
    };
  };
};

console.log(cartTotalPrice);

The readability aspect of this solution is subjective, but I just think this code looks a lot more human-friendly than methods and callback functions.

The for...of statements used here will also provide the ability to break-out of a given loop with the break statement. So in this context, if an item in the cart is matched to an item in products array in an iteration of the nested for...of loop, that same cart item won't be queried against the products array again in subsequent loops. With this specific dataset and solution, this brings the overall loops down from 8 to 3. You can probably imagine that with larger cart sizes and product catalogues, the performance benefits would be pretty significant.

Hope this helps.

CodePudding user response:

So specifically using the methods you want to use. You could do something like so. The main thing I change though is iterating the cart first and then using the find method to match the cart id to the product id.

const cart = [{
    _id: '624bc7fe0f91078261ab6529',
    qty: 1
  },
  {
    _id: '624bc8240f91078261ab6531',
    qty: 2
  }
]

const products = [{
    _id: '624bc7fe0f91078261ab6529',
    name: 'sample 1',
    price: 30,
    countInStock: 10
  },
  {
    _id: '624bc8240f91078261ab6531',
    name: 'sample 2',
    price: 10,
    countInStock: 4
  },
  {
    _id: '624bc1a50f91078261ab650d',
    name: 'sample 3',
    price: 15,
    countInStock: 1
  },
  {
    _id: '62562017645f1882e45adc32',
    name: 'sample 4',
    price: 20,
    countInStock: 7
  }
]

const cartTotals = [];
cart.forEach((product) => {
  const matchedProduct = products.find(element => element._id === product._id);
  if (matchedProduct) {
    cartTotals.push(product.qty * matchedProduct.price);
  }
});

console.log(cartTotals)

const totalAmount = cartTotals.reduce((a, b) => a   b, 0);

console.log(totalAmount);

CodePudding user response:

You can do it with a single forEach like this:

let total = 0;
cartInfo.forEach(productInCart => {
  const product = products.find(productExtended => productExtended.id === productInCart.id);
  total  = product.price * productInCart.qty;
});

But I would suggest to store the product's price inside cartInfo, that way you will not need to access products at all when counting the total

CodePudding user response:

Try using reduce function

const total = cartInfo.reduce((totalValue, currentCartItem) => {
  const foundProduct = products.find(product => product._id === currentCartItem._id);
  if (foundProduct) {
    totalValue  = foundProduct.price * currentCartItem.qty
 }
}, 0);

CodePudding user response:

Here is an example where you can get the subtotal for each item and then the total:

const cartInfo = [
  {_id: '624bc7fe0f91078261ab6529', qty: 1},
  {_id: '624bc8240f91078261ab6531', qty: 2}
]

const products = [
  {_id: '624bc7fe0f91078261ab6529', name: 'sample 1', price: 30, countInStock: 10},
  {_id: '624bc8240f91078261ab6531', name: 'sample 2', price: 10, countInStock: 4},
  {_id: '624bc1a50f91078261ab650d', name: 'sample 3', price: 15, countInStock: 1},
  {_id: '62562017645f1882e45adc32', name: 'sample 4', price: 20, countInStock: 7}
]

let subtotals = cartInfo.map(({_id, qty}) => {
  return { _id, subtotal: qty * products.find(p => p._id === _id).price }
})

let total = subtotals.reduce((total, item) => item.subtotal   total, 0)

console.log('Subtotals:', subtotals)
console.log('Total:', total)

  • Related