Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

LocalStorage updating element causes duplication with JSON in JQuery

So I'm trying to update an element in LocalStorage with JSON but I can't figure out what I am doing so wrong. I want to add a product and let its quantity be updated upon adding the same product again.

The first time I add X product, I get the correct quantity in one element. Upon adding another X, the quantity changes to null. Adding an entirely new product Y, will cause multiple duplicate Y elements with all null quantities.

There has to be some logical error that I just cannot seem to figure out. The addToCart function is where I suspect that things are going wrong. Any help is greatly appreciated as I am new to JavaScript and JQuery. Thank you.

$(document).ready(function() {
  // caching
  let $table = $(".shoe-table");

  fetch("shoes.json")
    .then(resp => resp.json())
    .then(data => {
      let shoes = data.shoes;
      let rows = [1, 2, 3];
      let shoeCard = "";
      let products = JSON.parse(localStorage.products || "[]");
      console.log(products);

      function addToCart(cBtn) {
        let clickedButton = $(cBtn);
        let buttonID = clickedButton.attr("id");
        let thisInput = $("#" + clickedButton.attr("id") + ".input-form").children("input");
        let newShoe = {
          id: buttonID,
          image: shoes[buttonID].image,
          name: shoes[buttonID].name,
          price: shoes[buttonID].price,
          quantity: parseInt(thisInput.val())
        };

        if (products.length != 0) {
          products.forEach(shoe => {
            if (shoe.name == newShoe.name) {
              shoe.quantity += newShoe.quantity;
              localStorage.setItem("products", JSON.stringify(products));
              console.log(products);
            } else {
              products.push(newShoe);
              localStorage.setItem("products", JSON.stringify(products));
            }
          });
        } else {
          products.push(newShoe);
          localStorage.setItem("products", JSON.stringify(products));
        }
      }

      let counter = 0;
      rows.forEach(row => {
        shoeCard += "<tr>";
        for (let index = 0; index < 4; index++) {
          shoeCard +=
            "<td class='card text-center'>" +
            "<img class='card-img-top' src=" +
            shoes[counter].image +
            " alt='Card image cap'>" +
            "<h5 class='card-title'>" +
            shoes[counter].name +
            "</h5>" +
            "<p class='card-text'>kr " +
            shoes[counter].price +
            "</p>" +
            "<button id=" +
            counter +
            " class='orderNow btn btn-outline-dark'>ORDER NOW</button>" +
            "<div id=" +
            counter +
            " class='input-form'><input class='qty-chooser' type='number' placeholder='Choose quantity' min=0 max=10>" +
            "<button class='btn-add-to-cart' disabled='disabled'>ADD TO CART</button>" +
            "</div>" +
            "</td>";
          counter++;
        }

        shoeCard += "</tr>";
      });

      $table.append(shoeCard);
      let $inputForm = $(".input-form");
      let $orderBtn = $(".orderNow");

      $inputForm.hide();

      let activeButton = -1;

      // Denna metod tittar om man redan har en aktiv beställning
      function isProductActive() {
        let btnID = $(this).attr("id");
        if (activeButton == -1) {
          activeButton = btnID;
          toggleOrder($(this));
        } else if (btnID != activeButton) {
          toggleOrder($("#" + activeButton + ".orderNow"));
          toggleOrder($(this));
          activeButton = btnID;
        } else if (btnID == activeButton) {
          toggleOrder($(this));
          activeButton = -1;
        }
      }

      $orderBtn.click(isProductActive);

      function toggleOrder(buttonC) {
        console.log("INSIDE TOGGLE");
        let clickedBtn = $(buttonC);
        let thisInputForm = $("#" + clickedBtn.attr("id") + ".input-form");

        let inputBtn = thisInputForm.children("button");
        let inputIn = thisInputForm.children("input");

        // RESETTAR ELEMENT I .input-form
        function resetInputForm() {
          inputBtn.css("background", "");
          inputBtn.css("color", "");
          inputBtn.attr("disabled", "disabled");
          inputIn.val(null);
        }

        // DENNA KNAPP ÄR EN ADD TO CART FUNKTION
        inputBtn.click(function() {
          // TODO: LÄGG TILL LOGIK FÖR ATT LÄGGA TILL VARUKORG
          console.log("INSIDE ADDING");

          addToCart(clickedBtn);
          thisInputForm.hide("slow");
          clickedBtn.text("ORDER NOW");
          clickedBtn.css("background", "");
          resetInputForm();
          activeButton = -1;
        });
        // BEROENDE PÅ QUANTITY REAGERAR ADD TO CART KNAPPEN
        inputIn.change(function() {
          let qty = inputIn.val();

          if (qty >= 1 && qty <= 10) {
            inputBtn.removeAttr("disabled");
            inputBtn.css("background", "rgb(15, 163, 10)");
            inputBtn.css("color", "white");
          } else if (qty < 1) {
            resetInputForm();
          } else if (qty > 10) {
            inputIn.val(10);
          }
        });

        // KONTROLLERAR ORDER NOW KNAPPEN
        if (clickedBtn.text() == "CANCEL") {
          thisInputForm.hide("slow");
          clickedBtn.text("ORDER NOW");
          clickedBtn.css("background", "");
          resetInputForm();
        } else {
          thisInputForm.show("slow");
          clickedBtn.text("CANCEL");
          clickedBtn.css("background", "red");
          inputBtn.attr("disabled", "disabled");
          resetInputForm();
        }
      }
    })
    .catch(err => console.error(err));
});
like image 657
PatrickS Avatar asked Mar 07 '20 16:03

PatrickS


2 Answers

Change the localStorage code with the below .The problem is that you are pushing all products on each forEach iteration to the localStorage.

Try the below code.

if (products.length != 0) {
  let isExists = products.some(shoe => shoe.name === newShoe.name);
  if (!isExists) {
    products.push(newShoe);
  } else {
      products = products.map(shoe => {
      if (shoe.name == newShoe.name && !isNaN(newShoe.quantity)) {
        shoe.quantity += newShoe.quantity;
        return shoe;
      }
      return shoe;
    });
  }
  localStorage.setItem("products", JSON.stringify(products));
} else {
  products.push(newShoe);
  localStorage.setItem("products", JSON.stringify(products));
}

like image 169
Sohail Ashraf Avatar answered Sep 22 '22 19:09

Sohail Ashraf


    if (products.length != 0) {
      for (let index = 0; index < products.length; index++) {
        if (products[index].name == newShoe.name) {
          products[index].quantity += newShoe.quantity;
          localStorage.setItem("products", JSON.stringify(products));    
          break;
        } else{
          products.push(newShoe);
          localStorage.setItem("products", JSON.stringify(products));  
          break;
        }
      }
    } else {
      products.push(newShoe);
      localStorage.setItem("products", JSON.stringify(products));
    }

This solves the problem with duplicates but still has issues with null quantities when adding a existing product.

like image 33
bob Avatar answered Sep 22 '22 19:09

bob