Avoid duplicate items from being added to an array in AngularJS

I have created an Angular Single Page Application that includes a cart feature where users can add items. My goal is to prevent users from adding the same item to the cart more than once.

function CartForm($scope) {

  $scope.products = [{
    "description": "BB-8 Droid",
    "qty": "1",
    "cost": "99"
  }, {
    "description": "C-3PO Droid",
    "qty": "1",
    "cost": "499"
  }, {
    "description": "R2-D2 Astromech Droid",
    "qty": "1",
    "cost": "899"
  }, {
    "description": "R5-D4 Astromech Droid",
    "qty": "1",
    "cost": "899"
  }, {
    "description": "IG-88 Bounty Hunter Droid",
    "qty": "1",
    "cost": "899"
  }];
  $scope.invoice = {
    items: []
  };

  $scope.addItem = function(product) {
      $scope.invoice.items.push(product);
    },

    $scope.removeItem = function(index) {
      $scope.invoice.items.splice(index, 1);
    },

    $scope.total = function() {
      var total = 0;
      angular.forEach($scope.invoice.items, function(item) {
        total += item.qty * item.cost;
      })

      return total;
    }
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

<h2>Shopping Cart Example</h2>
<div ng:controller="CartForm">
  <table class="table">
    <thead>
      <th>Description</th>
      <th>Qty</th>
      <th colspan="2">Price</th>
    </thead>
    <tr ng-repeat="product in products">
      <td>{{product.description}}</td>
      <td>{{product.qty}}</td>
      <td>{{product.cost | currency }}</td>
      <td>
        <button class="btn btn-danger" ng-click="addItem(product)">ADD TO CART</button>
    </tr>
  </table>
  <table class="table">
    <tr>

      <th>Description</th>
      <th>Qty</th>
      <th>Cost</th>
      <th>Total</th>
      <th></th>
    </tr>
    <tr ng:repeat="item in invoice.items">
      <td>
        <input type="text" ng:model="item.description" class="input-small">
      </td>
      <td>
        <input type="number" ng:model="item.qty" ng:required class="input-mini">
      </td>
      <td>
        <input type="number" ng:model="item.cost" ng:required class="input-mini">
      </td>
      <td>{{item.qty * item.cost | currency}}</td>
      <td>
        [<a href ng:click="removeItem($index)">X</a>]
      </td>
    </tr>
    <tr>
      <td></td>
      <td></td>
      <td>Total:</td>
      <td>{{total() | currency}}</td>
    </tr>
  </table>
</div>

Check out the live JSFiddle demo here: http://jsfiddle.net/tedleeatlanta/22591h2y/15/

Answer №1

If you want to streamline your AddItem function, you can implement some logic to handle all of the scenarios.

While it may not be the most elegant solution, the following approach will point you in the right direction:

    $scope.addItem = function(product) {
            var exists = false;
            for(var index = 0; index < $scope.invoice.items.length; index++){
                if ($scope.invoice.items[index].description == product.description)
                {
// Using parseInt here because the Qty isn't a number
                    $scope.invoice.items[index].qty  = parseInt($scope.invoice.items[index].qty) + 1;
                    exists = true;
                }
            }
            if (!exists)
                $scope.invoice.items.push(product);
        },

This code snippet updates the quantity if the item already exists, or adds it to the list if it does not.

You can test this implementation by running it at this link: http://jsfiddle.net/22591h2y/16/

Alternatively, if you prefer to avoid using parseInt, consider changing the qty property of your objects from strings to integers. Check out the modified version at: http://jsfiddle.net/22591h2y/17/

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

javascript implementing optional chaining for a single parameter

Is it possible to implement optional chaining on a single parameter? setAllProperties( Object.values(users).flatMap(({ properties }) => Object.values(properties) ) ); I am looking for a way to ensure that the properties folder exists in ...

Dynamic Bootstrap Popover: Creating interactive popups by dynamically attaching events to buttons

I am looking to implement the Bootstrap Popover module to create a confirmation dialog for a delete action. When a <button> is clicked, instead of immediately executing a function, I want a popup to appear allowing the user to either confirm or dismi ...

Troubleshooting the unsuccessful outcome of the node js async.map function

Context I am new to working with Node.js and the async module. I am encountering difficulties with making synchronous calls to my redis database. Objective My ultimate goal is to return a JSON object when the user calls my REST API's GET method. Th ...

Using the array.prototype.map method on props in React.js results in an array that is devoid

Recently, I've started exploring the world of React and encountered a problem while attempting to convert the value of props into a JSX element using array.prototype.map(). You can learn more about this method at this link. Here is a snippet of a Rea ...

What is the average time frame for completing the construction of an electron project?

My project has only a few npm dependencies, but the build process is taking longer than 30 minutes and still counting. I'm not sure if this is normal or if there's an issue causing the delay. I have two specific questions: Is it common for pro ...

When attempting to pass data to another page by clicking on a row, the result is that the data appears to be empty

I have been using the MUI-Datatable component, which is able to navigate to the next page. However, when I try to view the data on the History page, nothing appears. How can I resolve this issue? Data transfer to another page: Even though I can see the d ...

AngularJS - Organize Item Hierarchy with Separate Containers for Each Group

My goal is to incorporate a $scope variable within an AngularJS controller that has the following structure: $scope.hierarchy = { name: 'bob', selected: true, children: [ { name: 'frank' }, { name: 'spike' ...

Tips for getting information from a GET/POST response message with superagent

I'm currently utilizing Node.js and Superagent for testing my server implementation. I have successfully sent a Superagent GET request and received a positive response with the code provided below. My goal is to extract and log only the "id" value fro ...

Transferring a Variable from Arduino to JavaScript

Is there a simple way to pass an Arduino variable as a JS variable? Let's say we have an integer Arduino variable called sensorData: int sensorData = analogRead(sensorPin); How can we transfer this value to a JavaScript variable? client.println(&quo ...

Error: Unable to retrieve the name property of an undefined object within a React component that is being used as a child component within another parent component

FundraiserScreen.js // Import necessary components and dependencies; // Import Fundraiser component; const Children = ({ loading, error, fundraiserData }) => { if (loading) // Show skeleton loading HTML if (!error) return <Fundraiser fundraiser={fund ...

The input given to Material UI autocomplete is incorrect, even though the getOptionSelect parameter already exists

I'm currently working on creating my own version of the Google Places autocomplete found in the Material UI documentation. While I have successfully implemented the autocomplete feature and am able to update my component's state with the result, ...

Issues with selecting elements in AngularJS using CasperJS

I have attempted all solutions provided in the following link: How to fill a select element which is not embedded in a form with CasperJS? , as well as explored many other sources. The issue I am facing is that I am unable to modify the code below to inclu ...

What are the steps to ensure synchronous angular ajax calls?

function SubmitIdeaEvaluation(evaluationForm, ideaId, stageId, isEvaluated) { return $http({ url: SparkApp.FormEvaluation.SubmitIdeaEvaluation, method: "POST", contentType: "application/x-www-form ...

retrieving a URL with the help of $.getJSON and effectively parsing its contents

I seem to be struggling with a coding issue and I can't quite figure out what's wrong. My code fetches a URL that returns JSON, but the function is not returning the expected string: function getit() { var ws_url = 'example.com/test.js&ap ...

Setting a default action for an Ext.Ajax.request error situation

In my application, I frequently make ajax requests using the Ext.Ajax.request method. Often, I find myself skipping error handling for failed requests due to time constraints or lack of interest in implementing fancy error handling. As a result, my code us ...

Refreshable div element in a Code Igniter-powered web application

I am encountering difficulties with automatically refreshing my div using the CodeIgniter framework. My goal in the code snippet below is to have the particular div with id="lot_info" refresh every 1 second. The div is not refreshing, and an error message ...

Executing a sequence of jQuery's $.when().then() functions

I am facing challenges in understanding how to properly sequence my functions, especially in relation to the $.when() method. function y() { defer = $.Deferred(); $.when(defer).then(console.log(defer.state())); } y(); <script src="https://ajax.go ...

AJAX calls experiencing delays compared to standard HTTP requests

Hello everyone, We are facing a challenge while developing an Angular application and need help to improve its performance. Attached are two screenshots, one showing an AJAX request made within a larger page. The second screenshot shows the same request ...

Implementing optimistic updates with React-query mutations

Hello everyone! I'm a newcomer to react-query and I've been experimenting with making an optimistic update using the mutation function. However, I've encountered a problem where I'm unable to retrieve the previous value from the query. ...

How can data be transferred from a parent to a child component in Angular?

I'm facing an issue trying to pass the selected value from a dropdownlist in a user interface. I have a parent component (app.component.html) and a child component (hello.component.html & hello.component.ts). My goal is to transfer the option val ...