Search code examples
javascriptsumcalculationcumulative-sum

My calculation function won't work properly -- JavaScript


I'm currently working on a school project: I had to code a website that sells sofas. I made the whole site but I struggle with my calculation function that adds all the prices of each sofa to get the sum of my cart. It's always false whatever I do. I'm lost.

I had to fetch the prices of the products in my cart from the API and the products from the local storage. Then, I try to calculate the sum of all the prices within a specific function. I tried a loop but the result is always false.

Eg: When I add 2 sofas that cost 4499€ and one sofa of 1849€, the result is 5547 € instead of 10487€.

Getting sofas from LocalStorage : product name, photo and color only

function getCart() {
  let cart = localStorage‧getItem("cart");
  if (cart === null || cart === "[]") {
    let emptyCart = document‧querySelector("#cart__items");
    emptyCart‧innerText = "Votre panier est vide";
    document‧querySelector(".cart__order").style‧display = "none";
    return [];
  } else {
    return JSON‧parse(cart);
  }
}

Getting prices from API then adding display functions that need it

async function getPriceFromApi(article) {
  let dataFetch = await fetch(
    `http://localhost:3000/api/products/${article.id}`
  )
    .then((products) => products‧json())
    .then((product) => {
      return product;
    });

  const apiProduct = {
    price: dataFetch‧price,
  };

  const completeItem = {
    ...article,
    ...apiProduct,
  };

  productDisplay(completeItem);
  displayTotalPrice(apiProduct);
}

Calculation : the total price of the cart

function totalPriceCalculation(product) {
  let cart = getCart();
  let total = [];

  cart‧forEach((sumPrice) => {
    let number = eval(sumPrice‧quantity);
    total‧push(product‧price * number);
    console‧log(number, total);
  });
  let totalPrice = `${eval(total‧join("+"))}`;
  return totalPrice;
}

Displaying the whole cart (articles + prices) with every display and logic functions :

function completeCart() {
  let cart = getCart();
  displayTotalQuantity();

  cart‧forEach((item) => {
    getPriceFromApi(item);
  });
}

completeCart();

My display total price function :

function displayTotalPrice(product) {
  const TotalPrice = document‧querySelector("#totalPrice");
  TotalPrice‧innerText = totalPriceCalculation(product);
  return TotalPrice;
}

other functions : // THE main container

function container(DisplayArticle) {
  document‧querySelector("#cart__items").appendChild(DisplayArticle);
}

Here, I gather my query selectors for the images and desctiptions as well as my logic ("settings"= delete and modify) :

// The display function
function productDisplay(product) {
  const DisplayArticle = displayArticle(product);
  container(DisplayArticle);


// functions for the DOM : Query Selectors for HTML elements
  const DisplayImage = displayImage(product); 
  const DisplayDescription = displayDescription(product);

//functions "delete" and "modify quantities"
  const DisplaySettings = settings(product);

  DisplayArticle‧appendChild(DisplayImage);
  DisplayArticle‧appendChild(DisplayDescription);
  DisplayArticle‧appendChild(DisplaySettings);

  return DisplayArticle;
}

// Displaing all the articles (it works fine)

function displayTotalQuantity() {
  const AllItems = document‧querySelector("#totalQuantity");
  AllItems‧innerText = totalquantityCalculation();

  return AllItems;
}

function totalquantityCalculation() {
  let cart = getCart();
  let number = 0;

  cart‧forEach((sumItem) => {
    number += eval(sumItem‧quantity);
  });

  return number;
}
``

Solution

  • first thing first, IMO it's better that BE do the calculation..

    but yeah try this:

    1. getPriceFromApi should just return price
    2. should just gather data from localstorage getCart once in completeCart, hence totalquantityCalculation & totalPriceCalculation will receive cart params
    3. totalPriceCalculation will call getPriceFromApi on each product, hence it will be a promise which should call with await
    4. seperate totalPriceCalculation & totalquantityCalculation with displayTotalPrice & displayTotalQuantity, easier to read that

    async function getPriceFromApi(product) {
      try {
        const response = await fetch(
          `http://localhost:3000/api/product/${product.id}`
        );
        const dataFetch = await response.json();
    
        const completeItem = {
          ...article,
          ...dataFetch,
        };
        // not sure about this function
        productDisplay(completeItem);
    
        return dataFetch.price;
      } catch (e) {
        // do something when got error
      }
    }

    function displayTotalPrice(num) {
      const TotalPrice = document.querySelector('#totalPrice');
      TotalPrice.innerText = num;
    }
    
    function displayTotalQuantity(num) {
      const AllItems = document.querySelector('#totalQuantity');
      AllItems.innerText = num;
    }
    
    function totalquantityCalculation(cart) {
      let total = 0;
      cart.forEach((product) => {
        total += Number(product.quantity);
      });
      return total;
    }
    
    async function totalPriceCalculation(cart) {
      let totalPrice = 0;
      for (const product of cart) {
        const price = await getPriceFromApi(product);
        totalPrice += Number(price) * Number(product.quantity);
      }
      return totalPrice;
    }

    async function completeCart() {
      let cart = getCart();
    
      const totalQuantity = totalquantityCalculation(cart);
      displayTotalQuantity(totalQuantity);
    
      const totalPrice = await totalPriceCalculation(cart);
      displayTotalPrice(totalPrice);
    }
    
    completeCart();