Duplicates in ngOptions
Asked Answered
B

4

10

I am using AngularJS version 1.4.7 and have simple AngularJS controller which contains array of objects. I would like to display these objects as options in select by ngOptions.

The problem is that every object is duplicate and I don't know why. This duplicate is presented in the select only, the source object looks fine.

angular
  .module('demo', [])
  .controller('DemoCtrl', DemoCtrl);

function DemoCtrl() {
  var vm = this;
  
  vm.demoOptions = [
    {value: 1, label: 'Demo 1'},
    {value: 2, label: 'Demo 2'},
    {value: 3, label: 'Demo 3'}
  ];
  vm.selected = null;;
}
<script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.7/angular.min.js"></script>

<div ng-app="demo" ng-controller="DemoCtrl as vm">
  <select ng-options="item as item.label for item in vm.demoOptions track by item.value" ng-model="vm.selected">
    <option value="" selected ng-if="vm.selected === null">-- select --</option>
  </select>
  <p ng-if="vm.selected !== null">Selected item: <code>{{vm.selected}}</code></p>
  <p ng-if="vm.selected === null">No item is selected.</p>
  <pre>vm.demoOptions == {{vm.demoOptions|json}}</pre>
</div>

Is it a bug? How can I remove duplicates without using a filter?

Note: This problem has occurred after update AngularJS from version 1.3.19 to 1.4.7. I read the changelog but it tells only about addition of track by - I added it but with no effect.

Bidle answered 12/1, 2016 at 10:7 Comment(0)
F
2

It is a known bug for 1.4.x before 1.4.8 you can check issue.

If you have to use angularjs 1.4.7 version then you can use ng-show instead ng-if

You can find changelog and error from angularjs github

Fiduciary answered 12/1, 2016 at 10:27 Comment(3)
Ah, thank you. I made Google searches only with varieties of keyword duplicates.Bidle
acctually you don't need ng-show/ng-if in option : jsfiddle.net/aiubian/ja217g5v/2 (1.4.7)Deplore
@AnikIslamAbhi the OP would have the -- select -- disappeared as soon as you selected something. therefor you have to use ng-if or remove the option in version 1.4.7Snailfish
O
1

You have to remove your <option> tag from the <select> field. Since everything inside it will be used for every item and the <option> tag itself is generated through the directive of angularJS.

angular
  .module('demo', [])
  .controller('DemoCtrl', DemoCtrl);

function DemoCtrl() {
  var vm = this;
  
  vm.demoOptions = [
    {value: 1, label: 'Demo 1'},
    {value: 2, label: 'Demo 2'},
    {value: 3, label: 'Demo 3'}
  ];
  vm.selected = null;;
}
<script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.7/angular.min.js"></script>

<div ng-app="demo" ng-controller="DemoCtrl as vm">
  <select ng-options="item as item.label for item in vm.demoOptions track by item.value" ng-model="vm.selected" ng-change="vm.setSelected()">
  </select>
  <p ng-if="vm.selected !== null">Selected item: <code>{{vm.selected}}</code></p>
  <p ng-if="vm.selected === null">No item is selected.</p>
  <pre>vm.demoOptions == {{vm.demoOptions|json}}</pre>
</div>
Outlast answered 12/1, 2016 at 10:11 Comment(7)
you have to remove your <option> tag from the select field. since everything inside it will be used for every item. are you sure ?Deplore
@RaphaelMüller it shouldn't related with it as I almost use ng-options with non-value 'Please Select' option...Fiduciary
@AnikIslamAbhi In your Fiddle there is AngularJS version 1.4.8. So is it a bug in version 1.4.7?Bidle
in my office i am using angularjs 1.3 .. there is also working fine @AkarientaDeplore
@AnikIslamAbhi Sure sure I know. As I have written it worked well with version 1.3.19 but now I have to use version 1.4.7.Bidle
@AnikIslamAbhi you are right when you update it to 1.4.8 it is working,,,Fiduciary
@charlietfl please tell me, why it's working then and the OPs question not? if it's a bug in 1.4.7 where you have to remove the option, that this kind of requirement is working, the answer itself is not incorrect. maybe the answer is just not complete.Snailfish
A
1

angular
  .module('demo', [])
  .controller('DemoCtrl', DemoCtrl);

function DemoCtrl($scope) {
  var vm = this;
  
  vm.demoOptions = [
    {value: null, label: '--select--'},
    {value: 1, label: 'Demo 1'},
    {value: 2, label: 'Demo 2'},
    {value: 3, label: 'Demo 3'}
  ];
  vm.selected = vm.demoOptions[0];
  $scope.$watch(function(){ return vm.selected}, function(newVal, oldVal){
    if(!oldVal.value && newVal.value) {
     vm.demoOptions.shift();
    }
  });
  vm.setSelected = function(){
    
  }
}
<script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.7/angular.min.js"></script>

<div ng-app="demo" ng-controller="DemoCtrl as vm">
  <select ng-options="item.label for item in vm.demoOptions" ng-model="vm.selected" ng-change="vm.setSelected()">
    
  </select>
  <p ng-if="vm.selected !== null">Selected item: <code>{{vm.selected}}</code></p>
  <p ng-if="vm.selected === null">No item is selected.</p>
  <pre>vm.demoOptions == {{vm.demoOptions|json}}</pre>
</div>
Angieangil answered 12/1, 2016 at 10:17 Comment(5)
Interesting solution but I would like to hide the empty option when user select something.Bidle
It still doesn't have the requested effect.Bidle
sorry, it's my mistake. now you can checkAngieangil
I think, using this solution, you don't have any problems with angular versionsAngieangil
welcome, and thank you , because these question/discussion will helps to others who are using different angular versions.Angieangil
M
0

If you are experiencing this in 1.4.8 or greater the reason may be this bug. Duplicates can be created when using $compile. There are some workarounds on the bug page.

Melodee answered 5/1, 2018 at 17:31 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.