How to calculate discount for each item of an array using reduce()?

Viewed 131

I need to calculate 15% discount for each item in an array and the total.

Currently i have the solution for calculating and showing total discount for all items with reduce() method, but how do i calculate the discount for each item separately using reduce()? Is there a way to do that or should i use a different solution?

function getDomNodesBySelector(selector) {
  return Array.from(document.querySelectorAll(selector));
}

document.querySelector('.total__button').addEventListener('click', applyDiscount);

function applyDiscount() {
  let items = getDomNodesBySelector(".price-value");
  let numDiscount = 15;
  let totalValue = items.reduce((acc, cur) => acc + (1 - (numDiscount / 100)) * cur.innerText, 0);
  document.querySelector(".total-price-value").innerText = totalValue;
}
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Корзина заказов</title>
    <link rel="stylesheet" href="https://code.s3.yandex.net/web-code/entrance-test/lesson-2/task-2/fonts.css">
    <link rel="stylesheet" href="style.css">
  </head>
  <body class="page">
  <h1 class="page__title">Корзина</h1>
  <section class="chosen-items">
    <article class="card">
      <img src="https://code.s3.yandex.net/web-code/entrance-test/jacket.png" alt="" class="card__image">
      <div class="card__description">
        <h2 class="card__title">Have A Good Time x FA Two Tone куртка</h2>
        <p class="card__text">Цвет: Зеленый/Оранжевый</p>
        <p class="card__text">Размер: M</p>
        <p class="card__text">Количество: 1</p>
      </div>
      <div class="card__price">
        <p class="card__rub price-default"><span class="price-value">15890</span> руб.</p>
      </div>
    </article>
    <article class="card">
      <img src="https://code.s3.yandex.net/web-code/entrance-test/vans.png" alt="" class="card__image">
      <div class="card__description">
        <h2 class="card__title">Vans Old Skool кеды</h2>
        <p class="card__text">Цвет: Черный/Белый</p>
        <p class="card__text">Размер: 43</p>
        <p class="card__text">Количество: 1</p>
      </div>
      <div class="card__price">
        <p class="card__rub price-default"><span class="price-value">6390</span> руб.</p>
      </div>
    </article>
    <article class="card">
      <img src="https://code.s3.yandex.net/web-code/entrance-test/pop-DRS.png" alt="" class="card__image">
      <div class="card__description">
        <h2 class="card__title">Pop DRS Denim Stonewashed джинсы</h2>
        <p class="card__text">Цвет: Голубой</p>
        <p class="card__text">Размер: S</p>
        <p class="card__text">Количество: 1</p>
      </div>
      <div class="card__price">
        <p class="card__rub price-default"><span class="price-value">11290</span> руб.</p>
      </div>
    </article>
    <article class="card">
      <img src="https://code.s3.yandex.net/web-code/entrance-test/by-parra.png" alt="" class="card__image">
      <div class="card__description">
        <h2 class="card__title">By Parra ремень</h2>
        <p class="card__text">Цвет: Мульти</p>
        <p class="card__text">Размер: S</p>
        <p class="card__text">Количество: 1</p>
      </div>
      <div class="card__price">
        <p class="card__rub price-default"><span class="price-value">8550</span> руб.</p>
      </div>
    </article>
    <article class="card">
      <img src="https://code.s3.yandex.net/web-code/entrance-test/board.png" alt="" class="card__image">
      <div class="card__description">
        <h2 class="card__title">Fucking Awesome Drawings 2 Pink доска</h2>
        <p class="card__text">Цвет: Розовый флюросентный</p>
        <p class="card__text">Размер: Один размер</p>
        <p class="card__text">Количество: 1</p>
      </div>
      <div class="card__price">
        <p class="card__rub price-default"><span class="price-value">4790</span> руб.</p>
      </div>
    </article>
  </section>
  <section class="total page__total">
    <button class="total__button">Использовать купон на 15%</button>
    <div class="total__prices">
      <h2 class="total__title">Итого:</h2>
      <p class="total__rub price-default"><span class="total-price-value">46910</span> руб.</p>
    </div>
  </section>
  <script src="./task.js"></script>
  </body>
</html>
2 Answers

Something like

function getSingleValue(){

   var single = document.querySelector('.price-value').textContent;
   return single;

}

console.log(getSingleValue())

should give you an array with the individual prices from the html which you will then be able to use

While looping through the price items array, using reduce, you are already accessing each item element and calculating the discounted price for each item. So before updating the reduce accumulator update the item value.

Update each item and add to total:

// CHANGE:
// let totalValue = items.reduce((acc, cur) => acc + (1 - (numDiscount / 100)) * cur.innerText, 0);

// TO:
let totalValue = items.reduce((acc, cur) => {
    let itemdisc = (1 - (numDiscount / 100)) * cur.innerText; // calculate item discount
    cur.innerText = itemdisc; // update item
    return acc + itemdisc; // update total
}, 0);

And prevent discount from being applied again:

document.querySelector('.total__button').disabled = true;

Updated script:

function getDomNodesBySelector(selector) {
  return Array.from(document.querySelectorAll(selector));
}

document.querySelector('.total__button').addEventListener('click', applyDiscount);

function applyDiscount() {
  let items = getDomNodesBySelector(".price-value");
  let numDiscount = 15;
  let totalValue = items.reduce((acc, cur) => {
      let itemdisc = (1 - (numDiscount / 100)) * cur.innerText; // calculate item discount
      cur.innerText = itemdisc; // update item
      return acc + itemdisc; // update total
  }, 0);
  document.querySelector(".total-price-value").innerText = totalValue;

  // prevent discount from being applied more than once
  document.querySelector('.total__button').disabled = true;
}
Related