AngularJS ng-option

I created an object named Item1 and I want to create 2 subfields called field1 and field2 as given at the HTML below:

For field1:

<input ng-model="myItem.field1"></input>

For field2:

<select ng-model="myItem.field2" ng-init="myItem.field2=fieldOptions[0]" ng-options="val for myItem.field2 in fieldOptions" ng-change="changed(myItem)"></select>

Checkout that, I want to initialise my select form to the first element of an array called fieldOptions. I defined my field options as follows:

$scope.fieldOptions = [ 'opt1', 'opt2', 'opt3' ];

When I run this code I have the following error:

Error: [ngOptions:iexp] http://errors.angularjs.org/1.2.16/ngOptions/iexp?p0=myItem.field2NaNor%20myItem.field2%in%20policyNames&p1=%3Cselect%20ng-model%3D%22myItem.field2%22%20ng-init%3D%22myItem.field2%3DfieldOptions%5B0%5D%22%20ng-options%3D%22myItem.field2%for%20myItem.field2%in%20policyNames%22%20ng-change%3D%changed(myItem)%22%20class%3D%22ng-pristine%20ng-valid%22%3E
    at Error (native)
    at http://cdnjs.cloudflare.com/ajax/libs/angular.js/1.2.16/angular.min.js:6:450
    at n (http://cdnjs.cloudflare.com/ajax/libs/angular.js/1.2.16/angular.min.js:205:427)
    at link (http://cdnjs.cloudflare.com/ajax/libs/angular.js/1.2.16/angular.min.js:207:462)
    at J (http://cdnjs.cloudflare.com/ajax/libs/angular.js/1.2.16/angular.min.js:53:345)
    at f (http://cdnjs.cloudflare.com/ajax/libs/angular.js/1.2.16/angular.min.js:46:399)
    at f (http://cdnjs.cloudflare.com/ajax/libs/angular.js/1.2.16/angular.min.js:46:416)
    at J (http://cdnjs.cloudflare.com/ajax/libs/angular.js/1.2.16/angular.min.js:53:286)
    at f (http://cdnjs.cloudflare.com/ajax/libs/angular.js/1.2.16/angular.min.js:46:399)
    at f (http://cdnjs.cloudflare.com/ajax/libs/angular.js/1.2.16/angular.min.js:46:416) angular.js:9778
(anonymous function) angular.js:9778
(anonymous function) angular.js:7216
J angular.js:6582
f angular.js:5986
f angular.js:5989
J angular.js:6573
f angular.js:5986
f angular.js:5989
(anonymous function) angular.js:5891
(anonymous function) angular.js:1384
h.$eval angular.js:12412
h.$apply angular.js:12510
(anonymous function) angular.js:1382
d angular.js:3869
$b.c angular.js:1380
$b angular.js:1394
Wc angular.js:1307
(anonymous function) angular.js:21459
fire jquery-2.1.0.js:3047
self.fireWith jquery-2.1.0.js:3159
jQuery.extend.ready jquery-2.1.0.js:3365
completed

As far as I understand, the AngularJs compiler doesn't like ng-options definition. Because, when replace myItem.field2 with some other field name called otherfieldname as follows:

<select ng-model="otherFieldName" ng-init="otherFieldName=fieldOptions[0]" ng-options="otherFieldName for otherFieldName in fieldOptions" ng-change="changed(myItem)"></select>

It works as expected. Somehow, when I use a dot separated model name, it causes an error.

I also checked the this document for the directives designed for Select menu. In the ng-options part, the following forms are said to be valid for array data sources:

  • label for value in array
  • select as label for value in array
  • label group by group for value in array
  • select as label group by group for value in array track by trackexpr

As far as I understand, the label for value in array fits for me. Here, Array is $scope.fieldOptions in my case. But what shall label and value should be? Do they have to be the same or different? And why shouldn't I use dot separated models for label and value (i.e. myItem).

Do you have any idea?

JSFiddle is provided here.

you are confusing ng-model and ng-options

ng-options is used to construct the options only. The syntax can be a bit confusing but it is telling angular how to look at your array.

With a simple one dimensional array what you want is:

ng-options="val for val in fieldOptions"

Where fieldOptions is the scope array.

The variable name val can be anything you want like foo for foo in fieldOptions

DEMO

There are a number of problems with your code. The main problem seems to be that you are treating the list items as if they are an array of objects ("field1" and "field2"), but when you create the list, it's just an array of strings.

I also see problems with what you are doing with ng-init, and I'm not sure ng-model or your ng-change function are doing what you want.

I fixed up your fiddle to what I think you were going for:

http://jsfiddle.net/3HeFB/10/

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

myApp.controller("MainCtrl", ["$scope", function ($scope) {
    console.log("Main Controller loaded.");

    //create objects instead of strings
    $scope.fieldOptions = [{
        field1: 'opt1',
        field2: 'opt1Text'
    }, {
        field1: 'opt2',
        field2: 'opt2Text'
    }];    
    //default the var you use in ng-model to first item
    $scope.myItem = $scope.fieldOptions[0];
    console.log($scope.fieldOptions[0]);
    //change function does not get parameter passed
    $scope.changed = function () {
        console.log("Field2 changed.");
        console.log($scope.myItem);
    };
}]);