Anmol Singh Jaggi Anmol Singh Jaggi - 3 months ago 12
Javascript Question

Object.keys() not working in ng-options

I am trying to create a dropdown list using ng-options:

<!DOCTYPE html>
<html ng-app="m1">
<head>
<script src='https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.7/angular.min.js'></script>
</head>
<body ng-controller="c1">
<div>
Sort1
<select ng-model="sortKey1">
<option value="bookId">By Id</option>
<option value="bookTitle">By Title</option>
<option value="cost">By Cost</option>
</select>
</div>
<div>
Sort2
<select ng-model="sortKey2" ng-options="x for x in Object.keys(books[0])">
</select>
</div>
<div>
Sort3
<select ng-model="sortKey3" ng-options="x for x in bookKeys">
</select>
</div>
</body>
<script type="text/javascript">
var m1 = angular.module("m1", []);

m1.controller('c1',function($scope)
{
$scope.books = [
{
"bookId": 101,
"bookTitle": "Angular JS",
"cost":375,
},
{
"bookId": 102,
"bookTitle": "Instant AngularJS Starter",
"cost":150,
},
{
"bookId": 103,
"bookTitle": "Ng-Book: The Complete Book on AngularJS",
"cost":4657,
}];

console.log(Object.keys($scope.books[0]));
$scope.bookKeys = Object.keys($scope.books[0]);
});
</script>
</html>


I am trying to get the dropdown values from an object's keys by calling
Object.keys()
on an object and then using the resultant array in
ng-options
.

I am trying to create the effect of case 1. My attempt at case 2 is not working, however a similar thing implemented in case 3 is working.

Can anybody tell the reason why case 2 is not working?

Lex Lex
Answer

Angular has this functionality built in and probably doesn't understand Object.keys() as the source for ng-options. Change the <select> in your case 2 to:

<select ng-model="sortKey2" ng-options="key for (key,val) in books[0]">

Working example:

    var m1 = angular.module("m1", []);

    m1.controller('c1', function($scope) {
      $scope.books = [{
        "bookId": 101,
        "bookTitle": "Angular JS",
        "topic": "AngularJS",
        "author": "Green",
        "cost": 375,
      }, {
        "bookId": 102,
        "bookTitle": "Instant AngularJS Starter",
        "topic": "AngularJS",
        "author": "Dan Menard",
        "cost": 150,
      }, {
        "bookId": 103,
        "bookTitle": "Ng-Book: The Complete Book on AngularJS",
        "topic": "AngularJS",
        "author": "Ari Lerner",
        "cost": 4657,
      }];

      console.log(Object.keys($scope.books[0]));
      $scope.bookKeys = Object.keys($scope.books[0]);
    });
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.3/angular.min.js"></script>
<div ng-app="m1" ng-controller="c1">
  <div>
    Sort1
    <select ng-model="sortKey1">
      <option value="bookId">By Id</option>
      <option value="bookTitle">By Title</option>
      <option value="topic">By Topic</option>
      <option value="author">By Author</option>
      <option value="cost">By Cost</option>
    </select>
  </div>
  <div>
    Sort2
    <select ng-model="sortKey2" ng-options="key for (key,val) in books[0]">
    </select>
  </div>
  <div>
    Sort3
    <select ng-model="sortKey3" ng-options="x for x in bookKeys">
    </select>
  </div>
</div>

EDIT: If you want the value of a select option to not become the value of the object (for eg. 101, AngularJS etc.), you can write <select ng-model="sortKey2" ng-options="key as key for (key,val) in books[0]">