2

I'm having problems avoiding dupes with my code. Here is a simplified example. I know the problem is in the array object being a reference of the same scope variable, but what is the best way to avoid it?

<div ng-app="myApp">
  <div ng-controller="myCtrl">
    <input type="text" ng-model="item" />
    <div ng-repeat="item in items">
      {{ item }}
    </div>
    <button ng-click="save()">Save</button>
  </div>
</div>
<script>
  angular.module('myApp', []).
  controller('myCtrl', function ($scope) {
    $scope.items = [];
    $scope.save = function() {
      $scope.items.push($scope.item);
    }
  });
</script>

Here is a fiddle that demonstrates the problem: http://jsfiddle.net/u8Fuk/8/

2 Answers 2

3

Use track by syntax to fix this problem.

<div ng-repeat="item in items track by $index">
   {{ item }}
</div>

Here is a fiddle.

Sign up to request clarification or add additional context in comments.

Comments

2

Depends on what your goal is.

If you want to allow for duplicate values you need to change the code a bit as each item in the ngRepeat has to have a unique id. See the track by section here.

That would work like this:

<div ng-app="myApp">
  <div ng-controller="myCtrl">
    <input type="text" ng-model="item" />
    <div ng-repeat="item in items">
      {{ item.value }}
    </div>
    <button ng-click="save()">Save</button>
  </div>
</div>
<script>
  angular.module('myApp', []).
  controller('myCtrl', function ($scope) {
    $scope.items = [];
    $scope.save = function() {
        $scope.items.push({value:$scope.item});
    }
  });
</script>

See the updated fiddle here.

If you don't want to allow for the same values you need to search for it.

<div ng-app="myApp">
  <div ng-controller="myCtrl">
    <input type="text" ng-model="item" />
    <div ng-repeat="item in items">
      {{ item }}
    </div>
    <button ng-click="save()">Save</button>
  </div>
</div>
<script>
  angular.module('myApp', []).
  controller('myCtrl', function ($scope) {
    $scope.items = [];
    $scope.save = function() {
      var found = $scope.items.reduce(function(previous, i){
          if ($scope.item === i) return true;
          return previous;
        }, false);
      if (found){
        alert('duplicate value');
      }
      else{
        $scope.items.push($scope.item);
      }
    }
  });
</script>

See the updated fiddle here.

1 Comment

This works for anyone looking. It turns out in my specific case the input box is now tied to both objects in the array.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.