0

I have a select dropdown and I am populating it with an array of objects. I am also assigning a default value to it so that a specific option is selected by default. When I change the option to something else, the option value changes (you can see this in the pre tag), but the option label/text appears blank. If I try to select some other option now, it selects the option & also populates it's label/text correctly.

ISSUE:

So after the page loads, when I change the select option to a different value, the label/text does not populate. How to fix this so that the appropriate label shows up correctly?

Here is all my code:

 angular.module('myApp', [])
   .controller('TodoCtrl', TodoCtrl);

 function TodoCtrl($scope, $window) {
   $scope.fieldObj = {};
   $scope.allMembers = [{
     "member_id": "1",
     "firstname": "a"
   }, {
     "member_id": "2",
     "firstname": "b"
   }, {
     "member_id": "3",
     "firstname": "c"
   }, {
     "member_id": "4",
     "firstname": "d"
   }, {
     "member_id": "5",
     "firstname": "e"
   }, {
     "member_id": "6",
     "firstname": "f"
   }];

   $scope.allMembers.unshift({
     member_id: "new",
     firstname: "Add New"
   });
   $scope.fieldObj.firstName = {};
   $scope.fieldObj.firstName = {
     "member_id": "3",
     "firstname": "c"
   };
 }
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.0-rc.2/angular.js" rel="script"></script>
<div ng-app="myApp" class="container">
  <h2>Todo</h2>

  <div ng-controller="TodoCtrl">

    <select ng-model="fieldObj.firstName" ng-options="member.member_id as member.firstname for member in allMembers track by member.member_id">
      <option value=""></option>
    </select>

    <pre>
            {{fieldObj.firstName | json}}
            {{message}}
        </pre>

    <div ng-if="fieldObj.firstName === 'new'">New option was selected</div>

  </div>
</div>
Devner
  • 6,825
  • 11
  • 63
  • 104
  • Just change `$scope.fieldObj.firstName = {};` to `$scope.fieldObj.firstName = '3';`. And delete `$scope.fieldObj.firstName = { "member_id": "3", "firstname": "c" };`. – Stepan Kasyanenko Mar 11 '16 at 13:12

3 Answers3

1

I believe the issue is caused by having both select and track expressions in the same element; you can fix it by removing ".memberId" from the select part of ng-options, i.e.:

<select ng-model="fieldObj.firstName" ng-options="member as member.firstname for member in allMembers track by member.member_id">

Have a look at this codepen for an example; I've also changed some of your code slightly, e.g. the last line where you were assigning an object to fieldObj.firstName instead of to fieldObj itself.

Have a look at the "select as" section of https://docs.angularjs.org/api/ng/directive/ngOptions, which explains the problem in more depth.

Dan Belsey
  • 11
  • 1
1

This plunkr solves your problem: https://plnkr.co/edit/wij2MyHpgKVQndx4pawB?p=preview

The problem is, that you set your select's ng-model to fieldObj.firstName while setting a default value with the pattern of a member object.

Try using fieldObj directly as ng-model and preselect via ng-init:

 <select ng-init="fieldObj=allMembers[3]"  ng-model="fieldObj" ng-options="member as member.firstname for member in allMembers track by member.member_id">
      <option value=""></option>
 </select>

Also, you need to use case sensitive variable and property names: firstname is lowercase in your JSON but camel case in your template.

Related: How to make a preselection for a select list generated by AngularJS?

Community
  • 1
  • 1
FelixMelix
  • 278
  • 1
  • 8
0

You are assigning fieldObj.firstName to an object that contains both the firstName and the memberId, but I assume you are trying to assign the whole object, not one of the fields in it(firstName).

Try simplifying your ngOptions and everything should work:

angular.module('myApp', [])
   .controller('TodoCtrl', TodoCtrl);

 function TodoCtrl($scope, $window) {
   $scope.fieldObj = {};
   $scope.allMembers = [{
     "member_id": "1",
     "firstname": "a"
   }, {
     "member_id": "2",
     "firstname": "b"
   }, {
     "member_id": "3",
     "firstname": "c"
   }, {
     "member_id": "4",
     "firstname": "d"
   }, {
     "member_id": "5",
     "firstname": "e"
   }, {
     "member_id": "6",
     "firstname": "f"
   }];

   $scope.allMembers.unshift({
     member_id: "new",
     firstname: "Add New"
   });
   $scope.fieldObj = $scope.allMembers[2];
 }
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.0-rc.2/angular.js" rel="script"></script>
<div ng-app="myApp" class="container">
  <h2>Todo</h2>

  <div ng-controller="TodoCtrl">

    <select ng-model="fieldObj" ng-options="member.firstname for member in allMembers track by member.member_id">
      <option value=""></option>
    </select>

    <pre>
            {{fieldObj.firstName | json}}
            {{message}}
        </pre>

    <div ng-if="fieldObj.firstName === 'new'">New option was selected</div>

  </div>
</div>
Hristo Georgiev
  • 2,499
  • 1
  • 16
  • 23
  • 1
    Although the other answers provide the solution as well, I find this answer to be the most efficient with minimal changes. Hence I am accepting this & upvoting the rest. – Devner Mar 12 '16 at 03:54