0

I am trying to add items to an array that is stored to sessionStorage. The add function is supposed to check if the there is a matching value in the array and if so, add to the count of that item. If not, it should push the item onto the array.

For some reason the two functions work perfectly fine on their own but when combined in an if/else statement it either doesn't push the item onto the array or it adds to the count AND pushes a duplicate to the array.

I tried two different methods.

I'm new to JavaScript and jQuery and will appreciate any insight.

Method one:

$(".prodItem").on("click", ".addCart", function (e) {

cart = JSON.parse(sessionStorage.getItem('shopCart'));


let selectedProd = $(e.target).closest('.prodItem').find('.prodName').html();
console.log(selectedProd);
let selectedPrice = $(this).siblings('.price').html();
console.log(selectedPrice);
let count = 1;



$.each(cart, function (index, value) {
        if (selectedProd === value.prod) {
            value.count++;
            console.log(selectedProd);
            console.log(value.prod);
            storeCart();
            return;
        }
    });
    if ($.inArray(selectedProd, cart) !== -1) {
        // Add new product object to array
        let currentProd = new product(
            selectedProd,
            count++,
            selectedPrice);
        cart.push(currentProd);
    }

// Save array to sessionStorage
storeCart();
});

Method two:

$(".prodItem").on("click", ".addCart", function (e) {

cart = JSON.parse(sessionStorage.getItem('shopCart'));


let selectedProd = $(e.target).closest('.prodItem').find('.prodName').html();
console.log(selectedProd);
let selectedPrice = $(this).siblings('.price').html();
console.log(selectedPrice);
let count = 1;

for (let i = 0; i < cart.length; i++) {
    if (selectedProd === cart[i].prod) {
        value.count++;
        console.log(selectedProd);
        console.log(value.prod);
        storeCart();
        return;
    } else {
        let currentProd = new product(
            selectedProd,
            count++,
            selectedPrice);
        cart.push(currentProd);
    }
}
// Save array to sessionStorage
storeCart();

});

The HTML:

<div class="col-4 prodimg prodItem">
      <div class="card bg-light text-white rounded-circle shadow">
        <img class="card-img rounded-circle shadow" src="images/sofas/freud-sofa-1.jpg"
          alt="Camel coloured, corduroy Freud sofa">
        <div class="card-img-overlay crdimg" id="">
          <input class="form-check-input d-none" type="checkbox" id="checkboxFreud" value="" aria-label="...">
          <label class="card-title form-check" for="checkboxFreud">
            <h3 class="prodName">Frued Sofa</h3>
          </label>
          <label class="card-text form-check" for="checkboxFreud">
            <p>This piece is the perfect fit to liven up any space.<br>A comfortable six-seater with durable
              corduroy upholstery.<br><br>R<span class="price">56 988.00</span> (incl. VAT)<i
                class="btn bi bi-cart-plus ml-4 addCart"></i></p>
          </label>
        </div>
      </div>
    </div>

**NOTE: The empty cart array is created and stored before this section.

  • @RandyCasburn it is because .html() Returns: String - Description: Get the HTML contents of the first element in the set of matched elements. – JC_vd_Merwe_03 Nov 18 '21 at 22:59
  • @RandyCasburn the cart array is populated by selectedProd so where in the process does the apple become an orange and is there a way to work around it? – JC_vd_Merwe_03 Nov 18 '21 at 23:01
  • @RandyCasburn I don't think you understand the question because that part of my function works perfectly well and both console.logs return the same value. Thanks for trying though. – JC_vd_Merwe_03 Nov 18 '21 at 23:08
  • You are right, so this statement `$.inArray(selectedProd, cart)` - is looking into an array of `product` objects and attempting to find `selectedProd` - is `selectedProd` a `product` object? Or do you expect `.isArray()` to find a string in a list of object properties somehow? – Randy Casburn Nov 18 '21 at 23:27
  • Have you tried to check if exists in array with this method? It will help you check if value exists in array. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/includes – Wolffyx Nov 18 '21 at 23:34
  • @RandyCasburn will it make a difference if I create the currentProd object before I run `$.inArray()`? I tried `$.inArray(prod, cart)` and `$.inArray(procuct[prod], cart)` and nothing worked. Is there a way to convert it before hand perhaps? This is my second week of JavaScript/jQuery and my brain is mush from all the deep dive documentation. At this point I think I should just rewrite the whole method. – JC_vd_Merwe_03 Nov 19 '21 at 07:36
  • @Wolffyx I did, thanks. Also tried `indexOf()`. I think I am not accessing the object property correctly because each time I try any form of `if/else` it skips over that block of code. When I iterate with `$.each()` then it has no problem accessing the object property. – JC_vd_Merwe_03 Nov 19 '21 at 08:28
  • Try this https://codepen.io/wolffyx/pen/oNeVGXy. I changed a bit the names to understand the code – Wolffyx Nov 19 '21 at 17:47

2 Answers2

0

If I'm reading these the functions correctly, and to piggy back off of @Randy Casburn's answer, you may want to try using .text() instead of .html() to get the price value. If the the price elements are inputs, however, you'll likely want to use .value() instead.

  • Thanks for the input. The `selectedProd === value.prod` works perfectly, my bug is when I add `if ($.inArray(selectedProd, cart) !== -1)`. I need to find a way of checking for that value in the array and in my mind, if the `selectedProd === value.prod` works fine and everything in the rest of my code and other functions work fine, then there needs to be a way to check if that value exists in the array. – JC_vd_Merwe_03 Nov 18 '21 at 23:14
  • artDecor.js:116 Uncaught TypeError: $(...).closest(...).find(...).value is not a function at HTMLElement. (artDecor.js:116) at HTMLDivElement.dispatch (jquery.min.js:2) at HTMLDivElement.v.handle (jquery.min.js:2) – JC_vd_Merwe_03 Nov 18 '21 at 23:15
0

The answer was actually quite simple and I found it here:

I declared a boolean before running my $.each statement and then changed it if the product is found. The code now looks like this.

$(".prodItem").on("click", ".addCart", function (e) {
cart = JSON.parse(sessionStorage.getItem('shopCart'));
cart = cart != null ? cart : [];

let selectedProd = $(e.target).closest('.prodItem').find('.prodName').text();
console.log(selectedProd);
let selectedPrice = $(this).siblings('.price').text();
console.log(selectedPrice);
let count = 1;

let currentProd = new product(
    selectedProd,
    count,
    selectedPrice);

console.log($.type(cart));

let exists = false;                   <-- declare boolean

$.each(cart, function (index, value) {
        console.log($.type(cart));
        if (selectedProd === value.prod) {
            value.count++;
            console.log(selectedProd);
            console.log(value.prod);
            exists = true;            <-- change boolean
            storeCart();
        }
    });
if(!exists) {                         <-- check boolean
    cart.push(currentProd);
}

// Save array to sessionStorage
storeCart();
});