Angularjs select value is undefined

21,517

Solution 1

This is the classic "angular dot notation" issue.

Here is a working example

Basically, ng-switch creates a new scope, so when the select sets the selectedmethod property, it is doing so on the new scope, not the controller scope as you are expecting. One solution is to create a parent object for your model.

angular.module('app',[])
.controller('main', function($scope){
  $scope.selection = {};
  $scope.Memethods = ['Same as Card/Account Name','American Express','American Express Corp','Cash','Checking','MasterCard','My Visa','VISA'];
  $scope.companies = ['Company Paid','MyAMEX'];
})

and note how it's referenced differently in the html:

<select ng-model='selection.selectedmethod' ng-init="selection.selectedmethod=companies[0]" ng-switch-when='N' style='float:left'>
  <option ng-repeat='companyoption in companies' value="{{companyoption}}">{{companyoption}}</option>
</select>

A different (maybe better) way would be to use the "ControllerAs" syntax, which has the effect of doing this for you.

angular.module('app',[])
    .controller('main', function($scope){

      this.Memethods = ['Same as Card/Account Name','American Express','American Express Corp','Cash','Checking','MasterCard','My Visa','VISA'];
      this.companies = ['Company Paid','MyAMEX'];
    })

<body ng-app="app" ng-controller="main as main">
  <div class='subcontent'>
    <input id="me" type="radio" class='choosemethod' ng-model="paymentmethod" value="Y">
    <label for="me" class='choosemethod'>Me</label>
    <input id="company" type="radio" ng-model="paymentmethod" value="N" class='choosemethod'>
    <label for="company" class='choosemethod'>My Company</label>
    <br/>
    <span class='helptext'>Who makes payments to this account?</span><span class='help' style='margin-left:20px;width:20px;height:20px;'>help</span>
  </div>

  <div class='paymentmethods subcontent' ng-switch on="paymentmethod">
    <select ng-model='main.selectedmethod' ng-init="main.selectedmethod=main.Memethods[0]" id='methods' ng-switch-when='Y'>
      <option ng-repeat="method in main.Memethods" value="{{method}}">{{method}}</option>
    </select>

    <select ng-model='main.selectedmethod' ng-init="main.selectedmethod=main.companies[0]" ng-switch-when='N' style='float:left'>
      <option ng-repeat='companyoption in main.companies' value="{{companyoption}}">{{companyoption}}</option>
    </select>

    <div class='clear'></div>
    <label for='methods'>Payment Method</label><span class='help' style='margin-left:20px;width:20px;height:20px;'>help</span>

  </div>
  <div>{{main.selectedmethod}}</div>
</body>

Solution 2

you can refer to this simple example

html code :

<div ng-controller="Main" ng-app>
    <div>selections = {{selections}}</div>

    <div>
      <p>Model doesn't get updated when selecting:</p>
      <select ng-repeat="selection in selections" ng-model="selection" ng-options="i.id as i.name for i in items">
        <option value=""></option>
      </select>
    </div>

js code:

function Main($scope) {

    $scope.selections = ["", "id-2", ""];

    $scope.reset = function() {
        $scope.selections = ["", "", ""];
    };

    $scope.sample = function() {
        $scope.selections = [ "id-1", "id-2", "id-3" ];
    }

    $scope.items = [{
        id: 'id-1',
        name: 'Name 1'},
    {
        id: 'id-2',
        name: 'Name 2'},
    {
        id: 'id-3',
        name: 'Name 3'}];
}

Solution 3

The ng-model inside value must have Initialize before it represents. So the ng-init comes before the ng-model. inside the options $first is used for select the first value.

<select ng-init= "selectedmethod=companies[0]" ng-model='selectedmethod' ng-switch-when='N' style='float:left'>
    <option ng-repeat='companyoption in companies' value="{{companyoption}}" ng-selected="$first">{{companyoption}} 
    </option>
</select>
Share:
21,517
linyuanxie
Author by

linyuanxie

Updated on July 15, 2022

Comments

  • linyuanxie
    linyuanxie almost 2 years

    Now I am trying to get the value from select dropdown, but it return undefined. The thing is in html level it works as expect, Here is my code:

    <div class='subcontent'>            
      <input id="me" type="radio" class='choosemethod' ng-model="paymentmethod" value="Y"><label for="me" class='choosemethod'>Me</label>
      <input id="company" type="radio"  ng-model="paymentmethod" value="N" class='choosemethod'><label for="company" class='choosemethod'>My Company</label><br/>
      <span class='helptext'>Who makes payments to this account?</span><span class='help' style='margin-left:20px;width:20px;height:20px;'>help</span>
    </div>
    
    <div class='paymentmethods subcontent' ng-switch on="paymentmethod">
      <select ng-model='selectedmethod' ng-init="selectedmethod=Memethods[0]" id='methods' ng-switch-when='Y'>
        <option ng-repeat="method in Memethods" value="{{method}}">{{method}}</option>
      </select>
    
      <select ng-model='selectedmethod' ng-init="selectedmethod=companies[0]" ng-switch-when='N' style='float:left'>
        <option ng-repeat='companyoption in companies' value="{{companyoption}}">{{companyoption}}</option>
      </select>
    
      <div class='clear'></div>
      <label for ='methods'>Payment Method</label><span class='help' style='margin-left:20px;width:20px;height:20px;'>help</span>
    </div>
    

    In js:

    $scope.Memethods = ['Same as Card/Account Name','American Express','American Express Corp','Cash','Checking','MasterCard','My Visa','VISA'];
    $scope.companies = ['Company Paid','MyAMEX'];
    

    it shows fine in page, but when I try to get the value, it shows undefined. any idea?

  • linyuanxie
    linyuanxie over 9 years
    This is what I need, I thought it could be scope problem, but couldn't know where and why. Thanks man!
  • GregL
    GregL over 9 years
    Well explained, though I believe your code example for the "controller as" syntax is not 100% correct - don't you need to change the rest of the references to Memethods and companies to be main.Memethods/main.companies? Anything that is a property of the controller instance is only available on the scope via the scope property, which in this case is "main".
  • Joe Enzminger
    Joe Enzminger over 9 years
    That's what I get for putting an answer together on an ipad. Edited. Thx