Exploring a JavaScript array of items and verifying the presence of a specific value before making updates or appending new data

Previous inquiries have delved into similar topics including Determining if an array contains a specific value and Checking for a value in an array using JavaScript, but none of them have provided a solution to my particular issue.

The comments within my code outline the specifics of what I am attempting to accomplish.

// I have initialized an empty array that will store items added via an onclick function
var list = []
// The following is my 'add to cart' function
function addToCart(productName, productPrice, url, description, quantity) {
// First check if the list is empty; if so, simply add the item to the cart without looping through
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 iterate through
} else {
for (var i = 0; i < list.length; i++) {
// If the product name of the clicked item already exists in the array 
// do not add it again, instead increment its quantity by 1
   if (list[i].name === productName) {
list[i].quantity++
console.log('same product, no need to add - increasing quantity by 1 ')
console.log(list)
} else {
 // If the clicked product does not exist in the list, add it as a new entry
 // A problem arises when there is only one item in the list
 // Everything functions properly when there are two different products in the list
 // However, when clicking on an existing item, the quantity increments and adds the same item
 list.push({ name: productName, price: productPrice, url: url, quantity: 1 });
 console.log('new item added since it did not previously exist')
console.log(list)
}
}
    }
}

The following are the console logs:

First click:

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

Second click on the same product:

same product, no need to add - increasing 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 selecting a different product resulting in two distinct items in the list:


new item added since it did not previously exist
 (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)

Upon clicking on 'Cucumber Poinsett / kg' again, instead of updating the quantity, it is being added as a new entry.

This is where I am encountering issues that I cannot pinpoint:

new item added since it did not previously exist
(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
``

Answer №1

A common mistake is performing additional actions within each iteration, which is not ideal

What should be done is to check and match the value in the first element; if it matches, then update it, otherwise add a new item to the cart

This process occurs before moving on to the next iteration

The correct approach is to only check for conditions inside the loop and maintain a flag for it

If the flag remains untouched until the loop exits, it indicates that the item is not present in the array at all

In such cases, a new item can be added to the cart

var exist = false;
for (var i = 0; i < list.length; i++) {
    //if the product name of the clicked item is already in the array
    //then there's no need to add it, simply increment its quantity by 1
    if (list[i].name === productName) {
        list[i].quantity++;
        console.log('The same product already exists, so we are incrementing the quantity by 1');
        console.log(list);
        exist = true;
    }
}

if(!exist){
    // If 'exist' remains false, it means the item is definitely not in the array

    // If the name of the clicked product does not exist in the array, add it
    // The issue arises when there is more than one product type in the list
    // Clicking on an item may inadvertently increment its quantity and add it again
    list.push({ name: productName, price: productPrice, url: url, quantity: 1 });
    console.log('Item does not exist, adding now')
    console.log(list)
}

Answer №2

From my perspective, the main issue seems to stem from the current implementation. While the code is logical, it is also complex and lacks efficiency.

A more effective approach could involve utilizing a different data structure like a Map (Hash Map/Hash Table).

The drawback of using a Map arises when considering support for IE. In such cases, using a JavaScript Object would be preferable.

If you only need support for IE11 and newer, consider exploring JavaScript Map.

Otherwise, opting for a key/value data structure offers several advantages:

  1. Removing items becomes simpler and tidier
  2. No loops are required
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);

Although using the same reference for cart at this stage may call for implementing a Cart prototype, the provided solution showcases a better approach!

Hope this proves helpful!

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})

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Navigating the website with curtain.js and anchor tags

Currently, I am working on a website located at www.TheOneCraft.co.uk. I have incorporated the curtain.js jQuery plugin to create animated slide/pages as users scroll down. However, I have been unsuccessful in making the navigation bar follow this animati ...

Synchronizing the DOM with the Database in a React Component/View: A Step-by-Step

I recently developed a list component in React, but I'm facing two significant challenges. Although the item gets removed from the database, the change is only visible after refreshing the page. You might have noticed that the list number or ID colu ...

Seeking a POST request to a specific URL

Hey there! I'm currently working on developing an Airtime application and need some guidance. Here's what I need help with: To send airtime, I have to make a HTTP POST request to one of the following endpoints: Live: Sandbox: These are the req ...

Issue with ng-disabled not functioning properly for href tag within list item

Is there a way to prevent clicking on the <a> tag within a list item in a UI list so that the associated <div> is not displayed when clicked (excluding the last list item)? I have attempted using ng-disabled directly on the list item attribute ...

Encountering a bug in my JSON or object tree viewer in Vue.js 3 where duplicate keys are present when there are multiple similar values

Encountering an issue with the following code: Attempting to create a tree viewer from an object, it works well until encountering identical values which cause key duplication and replacement. View on CodePen: https://codepen.io/onigetoc/pen/rNPeQag?edito ...

Transform your TypeScript code with a jscodeshift codemod that removes generic type declarations while preserving the wrapped

I am currently working on developing a codemod that will eliminate all instances of the $ReadOnly<T> generic from a TypeScript codebase, while retaining only T (where T represents an object or union). This is what I have managed to come up with so f ...

What is the best way to choose dropdown values by utilizing various button IDs?

I have four different vacation destinations and four buttons. I want to automatically select each destination separately when the corresponding button is clicked. <select class="aa" required="" name="f1990" {input.multiple}="" {input.size}="" id="f19 ...

Filtering collections by value in a field using Meteor.js

Currently, I am working on a project in meteor.js where I need to retrieve all collections with a specific value in one of their fields: Posts.insert({ tags: ['test', 'test1', 'test2'], categories: ['test', &a ...

Troubleshooting Problems with POST Requests in ExpressJS

Currently, I am working on developing a feature in NodeJS that allows users to upload files. However, I am encountering difficulties while attempting to make a simple POST request. In my index.ejs file, I have written code that generates a form and initia ...

"Enhancing Angular 2 with a robust HTTP retry system

My API uses token-based authentication for security. Once a user successfully signs in, two tokens (access and refresh) are stored in the browser's local storage. The access token contains all the necessary information for server-side authorization an ...

Tips for passing the element ID as an argument in the jQuery upvote plugin function

var updateVote = function(data) { $.ajax({ url: '/vote/', type: 'post', data: { id: data.id, up: data.upvoted, down: data.downvoted, ...

What is the best way to sort through observable JSON file responses?

In the midst of my angular project, I have been assigned the challenge of filtering a massive file based on the "_type" key, which can hold various values. My current objective is to initiate the filtration process for _type = "COMPETITION". The structure ...

Optimally organize a 2D numpy array using a pair of 1D arrays for indexing

In my programming dilemma, I have a sizable 2D numpy array along with two 1D arrays that serve as x/y indexes within the 2D array. My goal is to use these 1D arrays to carry out an operation on the 2D array. While a for loop can achieve this task, it prove ...

What is the most effective method to verify if all elements in an array fall within a specified range

What is the most effective method to verify if all array values fall within a specific range? For instance: $range = range(10, 40); $array1 = array(10, 20, 40); // OK $array2 = array(11, 22, 42, 30); // FALSE $array3 = array(50); // OK $array4 = arra ...

Search for elements within the database by using the recursive feature of M

I am working on a search query to retrieve 'n' number of videos from a collection. The user has primary, secondary, and tertiary language preferences (Tamil(P), Hindi(S), English(T)). My goal is to first search for videos in the primary language, ...

Is it possible to connect to the Oculus Go controller using the GamePad API within the Oculus Browser

Exploring my three.js apps on the new Oculus Go has led me to question whether I can interact with the controller solely through the GamePad API supported by major browsers. Although Oculus documentation suggests using OVRManager in Unity or Unreal Bluepri ...

personalizing material-ui component styles – set select component color to be pure white

I am looking to implement a dropdown menu using material-ui components (refer to https://material-ui.com/components/selects/). To do so, I have extracted the specific component from the example: Component return <div> <FormControl variant="outli ...

A unique issue arises when custom geometry is registered in A-Frame but fails to render once added to a scene

I have developed custom functions to create non-hollow THREE.js geometries with phi length values that are less than 360. Now, I want to display them in an A-Frame scene (embedded within React). However, I am facing issues while trying to render them. Ini ...

Preventing PCs from accessing a specific webpage: A step-by-step guide

I am currently using the code below to block phones: if { /Android|webOS|iPhone|iPad|iPod|BlackBerry|BB|PlayBook|IEMobile|Windows Phone|Kindle|Silk|Opera Mini/i .test(navigator.userAgent)) { window.location = "www.zentriamc.com/teachers/error ...

Tips for designing a hyperlink insertion modal while preserving text selection

I am working on a React website that utilizes Slate-React () for creating a rich text input field. Currently, Slate uses the browser's prompt() function to add hyperlinks to selected text. However, I need to customize the styling of the prompt modal a ...