tom gates
tom gates

Reputation: 111

How to loop through javascript array of list and check if value exist then update else add new data

Similar questions have been answered here Determine whether an array contains a value and here How do I check if an array includes a value in JavaScript? , but none of them seems to solve my problem.

The comments in my code explain the details of what I want to achieve.

// I have an empty array that i will add items to it using onclick function
var list = []
//Now here is my add to cart function
function addToCart(productName, productPrice, url, description, quantity) {
//First check if the list is empty, then no need to loop through you just add the item to cart
if (list.length === 0) {
list.push({ name: productName, price: productPrice, url: url, quantity: 1 });
 console.log(list)
 console.log('adding first item')
 //if not empty then loop through
} else {
for (var i = 0; i < list.length; i++) {
//if the product name of the item clicked in already in the array 
//then no need to add but get the quantity and increment it by 1
   if (list[i].name === productName) {
list[i].quantity++
console.log('same product not adding, we are incrementing the quantity by 1 ')
console.log(list)
} else {
 // if the name of product clicked  does not exist then add it to the list
 // here is where there problem comes, when there is only one product in the list 
 // everything works fine, but when there are two different kinds of products in the list 
 //  as shown in a console log below, then you click on
 // one of these items it increment the quantity then add the same item again
 list.push({ name: productName, price: productPrice, url: url, quantity: 1 });
 console.log('does not exist, am adding now')
console.log(list)
}
}
    }
}

Here are the console logs:

First time click:

[{ … }]
0: { name: "Bell pepper", price: "3", url: "https://firebasestora…=media&tokenc", quantity: 1 }
length: 1
__proto__: Array(0)

Second time click on the same product:

same product not adding, we are incrementing the quantity by 1
[{ … }]
0:
name: "Bell pepper"
price: "3"
url: "https://firebasestorage.googleapis.com/v0/b/ps-farms.appspoc"
quantity: 2
__proto__: Object
length: 1
__proto__: Array(0)

First time click on a different product to have two different list of items in list:


does not exist, am adding now
 (2)[{ … }, { … }]
0: { name: "Bell pepper", price: "3", url: "https://firebasestoc", quantity: 2 }
1: { name: "Cucumber Poinsett/kg", price: "7.5", url: "https://firebasest", quantity: 1 }
length: 2
__proto__: Array(0)

Now when I click on Cucumber Poinsett / kg again, instead of updating the quantity it add it again.

That is where I don't know where the error is coming from:

does not exist, am adding now
(3)[{ … }, { … }, { … }]
0: { name: "Bell pepper", price: "3", url: "https://firebasesto/4858c", quantity: 2 }
1: { name: "Cucumber Poinsett / kg", price: "7.5", url: "https://firebasestorage.c74c", quantity: 1 }
2: { name: "Cucumber Poinsett / kg", price: "7.5", url: "https://firebasest74c", quantity: 1 }
length: 3
``

Upvotes: 1

Views: 3011

Answers (2)

Sarfraaz talat
Sarfraaz talat

Reputation: 635

You are instantly doing else inside each iteration, which is wrong

What this does is, it check & matches value in first element, if matches then it does update else it adds new item in cart

This happens before going to second iteration

what you should do is check only if inside loop & maintain a flag for it

If the flag is untouched till the loop exists, means the item is not in the array at all

Here you can add new item in cart

var exist = false;
for (var i = 0; i < list.length; i++) {
    //if the product name of the item clicked in already in the array 
    //then no need to add but get the quantity and increment it by 1
    if (list[i].name === productName) {
        list[i].quantity++;
        console.log('same product not adding, we are incrementing the quantity by 1 ');
        console.log(list);
        exist = true;
    }
}

if(!exist){
    // IF  EXIST is still false, the item is definately nowhere inside the array

    // if the name of product clicked  does not exist then add it to the list
    // here is where there problem comes, when there is only one product in the list 
    // everything works fine, but when there are two different kinds of products in the list 
    //  as shown in a console log below, then you click on
    // one of these items it increment the quantity then add the same item again
    list.push({ name: productName, price: productPrice, url: url, quantity: 1 });
    console.log('does not exist, am adding now')
    console.log(list)
}

Upvotes: 2

Leo Borai
Leo Borai

Reputation: 2509

How I see this, I think your first issue comes from the kind of implementation. The code is intuitive but the problem is that is also complex and leaks performance.

A better implementation could be achieved using another data structure such as a Map (Hash Map/Hash Table).

The downside of using Map comes if you should support IE or not. Otherwise use a JavaScript Object.

Please checkout JavaScript Map if you only want support for IE11 and newer.

Otherwise using a key/value data structure is a great idea:

  1. Removing items is easier and cleaner
  2. No loops needed
const cart = {};

// handle click
function handleClick(product) {
  if (product.id in cart) {
    // Updates quantity by one
    cart[product.id] = {...cart[product.id],
      // Update values for this product in the cart
      quantity: cart[product.id] + 1
    }
  } else {
    Add product to cart object
    cart[product.id] = product;
  }
}

// Turn into array if necessary
Object.values(cart);

At this point, as Im using the same reference for cart, I think you could implement a Cart prototype, but for a quick sample of what I think is a better approach that's it!

Hope it helps!

my html code

{% block content %}
   {% for doc in product %}
<div class="jumbotron">
<div class="col-sm-4">
<div class="card" >
 <div class="card-body">
<a href="#" class="img-prod"><img class="img-fluid" id="productUrl" src="{{doc.productImage}}"  alt="{{doc.productName}}">
 <h1 class="card-title" id="productName">{{doc.name}}</h1>
 <p class="card-subtitle mb-2 text-muted" id="productPrice">{{doc.price}}</p>
 <p class="card-text" id="productDescription">{{doc.description}}</p>
<button type="button" onclick="addToCart('{{doc.productName}}','{{doc.price}}','{{doc.productImage}}','{{doc.description}}')">Add to cart</button>
 </div>
 </div>
</div>
</div>
{% endfor %}
{% endblock content %} 

Django view.py

def home(request):
    collection_ref = db.collection(u'products').get()
    documents = list(doc.to_dict() for doc in collection_ref)
    return render (request,'store/home.html',{'product':documents})

Upvotes: 0

Related Questions