4

Snippet 1:

  • If you run this below code, then you can't add duplicate records.

var app = angular.module("myShoppingList", []);
app.controller("myCtrl", function($scope) {
  $scope.products = ["1", "2", "3"];
  $scope.addItem = function() {
    $scope.products.push($scope.addMe);
  }
});
<html>
<head>
  <link rel="stylesheet" href="style.css">
  <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.5/angular.js"></script>
</head>
<body>
    <div ng-app="myShoppingList" ng-controller="myCtrl">
      <ul>
        <li ng-repeat="x in products">{{x}}</li>
      </ul>
      <input ng-model="addMe">
      <button ng-click="addItem()">Add</button>
    </div>
    <p>Write in the input field to add items.</p>
  </body>
</html>

And the above snippet throws an error for

"[ngRepeat:dupes] Duplicates in a repeater are not allowed. Use 'track by' expression to specify unique keys. Repeater: x in products, Duplicate key: string:1, Duplicate value:


Snippet 2:

  • But you can add duplicate value on first time if you run this below snippet . But it's does not allow to add duplicate values while clicking on second time.

var app = angular.module("myShoppingList", []);
app.controller("myCtrl", function($scope) {
  $scope.products = [1, 2, 3];
  $scope.addItem = function() {
    $scope.products.push($scope.addMe);
  }
});
<html>
<head>
  <link rel="stylesheet" href="style.css">
  <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.5/angular.js"></script>
</head>
<body>
    <div ng-app="myShoppingList" ng-controller="myCtrl">
      <ul>
        <li ng-repeat="x in products">{{x}}</li>
      </ul>
      <input ng-model="addMe">
      <button ng-click="addItem()">Add</button>
    </div>
    <p>Write in the input field to add items.</p>
  </body>
</html>

Snippet Code Difference :

Snippet 1 - $scope.products = ["1", "2", "3"]; // string values

Snippet 2 - $scope.products = [1, 2, 3]; // integer values


Question:

  • Why angular does not allowing to add duplicate value on first time if the array values are string?
  • Why angular is allowing to add duplicate value on first time if the array values are integer
  • Why angular does not allow duplicate value on second time if the array values are integer
Ramesh Rajendran
  • 37,412
  • 45
  • 153
  • 234

3 Answers3

1

It is because by default input type is text therefore string, so number 2 is not equel to string "2"

if you add type number to your input

<input type="number" ng-model="addMe"> 

in your 2nd example you would see that it will not allow duplicate entry

var app = angular.module("myShoppingList", []);
app.controller("myCtrl", function($scope) {
  $scope.products = [1, 2, 3];
  $scope.addItem = function() {
    $scope.products.push($scope.addMe);
  }
});
<html>
<head>
  <link rel="stylesheet" href="style.css">
  <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.5/angular.js"></script>
</head>
<body>
    <div ng-app="myShoppingList" ng-controller="myCtrl">
      <ul>
        <li ng-repeat="x in products">{{x}}</li>
      </ul>
      <input type="number" ng-model="addMe">
      <button ng-click="addItem()">Add</button>
    </div>
    <p>Write in the input field to add items.</p>
  </body>
</html>
NTP
  • 4,338
  • 3
  • 16
  • 24
  • Yup. This sound is nice. But whatever it is. `ng-repeat` should be check it if the string value is an number. I think it is a minor bug in `ng-repeat` – Ramesh Rajendran Mar 12 '18 at 12:04
  • In my opinion it is not a bug but it is wrong implementation as in the above example a string value is added to integer array. – NTP Mar 13 '18 at 09:26
1

Angular needs to keep track of the array item in the repeater. If no track by field is specified then it tracks by creating the hash of the array item.

Based on above the answers to your questions will be as follows

Why angular does not allowing to add duplicate value on first time if the array values are string?

It creates the same hash for duplicate values - hence, the error

Why angular is allowing to add duplicate value on first time if the array values are integer

Because when you enter again, it is treated as a string and hence, has different hash.

Why angular does not allow duplicate value on second time if the array values are integer

Because first entry is treated as string and hence the second entry considered as duplicate.

Nikhil Aggarwal
  • 28,197
  • 4
  • 43
  • 59
1

I debugged the code and found below points

When you are adding the value from the input box, it is treating it as a string, not as a number.

In the first case

It contains a list of strings. Consider you try adding 3. It treat the input as "3" which is already present, hence it gives error.

In the seconds case

You have an array of numbers. When when you first time insert an item say 3, it will get added as a string. So 3(integer) is not the same as "3"(string).

Rakesh Burbure
  • 1,045
  • 12
  • 27