0

I'm ran across the following that I found to be strange. I'm not blocked by it but was curious if someone knew. When I use hasOwnProperty with a select option, it shows a value (A2F0C7) not in the dropdown as selected.. Can anyone share why this is happening? Here is the jsfiddle:

http://jsfiddle.net/stampyNY/2oeo8of9/1/

<div ng-controller="TestCtrl">
    <select>
        <option ng-repeat="(k,v) in items" ng-show="v.hasOwnProperty('test')" value="{{k}}">{{k}}</option>
    </select>
var app = angular.module('app', []);

function TestCtrl($scope) {
    $scope.items = {
                 'A2F0C7':{'secId':'12345', 'pos':'a20'},
                 'C8B3D1':{'pos':'b10'},
                 'WAM':{'test': 1, 'pos':'b10'}
               };
}

Thank You!

Daniel Cohen
  • 538
  • 1
  • 4
  • 6

2 Answers2

0

In angularJS, when you add "ng-show={{expression}}", the expression will be validated (either to true or false) and add the style "display: none;" respectively. As a result, you will have something rendered in your HTML:

<select>
    <!-- ngRepeat: (k,v) in items -->
    <option ng-repeat="(k,v) in items" ng-show="v.hasOwnProperty('test')" value="A2F0C7" class="ng-scope ng-binding" style="display: none;">A2F0C7</option>
    <option ng-repeat="(k,v) in items" ng-show="v.hasOwnProperty('test')" value="C8B3D1" class="ng-scope ng-binding" style="display: none;">C8B3D1</option>
    <option ng-repeat="(k,v) in items" ng-show="v.hasOwnProperty('test')" value="WAM" class="ng-scope ng-binding">WAM</option>
</select>

With this style added, the value won't be showed in your drop down box, but by default the first value will be selected for html select tag. That's the reason why you see this value (although it shouldn't).

To fix this,simply update your code by adding ng-selected:

<select>
    <option ng-repeat="(k,v) in items" ng-show="v.hasOwnProperty('test')" ng-selected="v.hasOwnProperty('test')" value="{{k}}">{{k}}</option>
</select>
Duy Nguyen
  • 226
  • 3
  • 6
0

As was previously posted ng-show just controls the visibility of the DOM object which does not prevent it from beeing selected initially. It would be preferable to not create the actual DOM element for entries which shouldn't be visible.

This could be done using a custom filter:

app.filter('filterTestProperty', function() { 
   return function(values) {
      var result = {};
      for (var key in values){
          var value = values[key];
          if (value.hasOwnProperty('test')){
              result[key] = value;
           }
      }
      return result;
   }
});

And the HTML:

<option ng-repeat="(k, v) in items | filterTestProperty" value="{{k}}">{{k}}</option>

var app = angular.module('app', []);

app.filter('filterTestProperty', function() {
  return function(values) {
    var result = {};
    for (var key in values) {
      var value = values[key];
      if (value.hasOwnProperty('test')) {
        result[key] = value;
      }
    }
    return result;
  }
});

app.controller('TestCtrl', function TestCtrl($scope) {
  $scope.items = {
    'A2F0C7': {
      'secId': '12345',
      'pos': 'a20'
    },
    'C8B3D1': {
      'pos': 'b10'
    },
    'WAM': {
      'test': 1,
      'pos': 'b10'
    }
  };
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app" ng-controller="TestCtrl">
  <select>
    <option ng-repeat="(k, v) in items | filterTestProperty" value="{{k}}">{{k}}</option>
  </select>
</div>
Denis Thomas
  • 1,012
  • 1
  • 8
  • 17