0

I'm new to angularjs and I really need help with this issue.

csApp.controller('expensesCtrl', function ($scope, $http) {
        $scope.getExpenses = function () {
            $http.post('/Home/ExpensesTableList').then(function (response) {
                $scope.vendorList = response.data.csVendors;
                $scope.list = response.data.csExpenses;
            });
        };
        $scope.getExpenses();
    });

// returned json
{"csExpenses":[{"vendorNo":1}],
 "csVendors":[{"vendorNo":1,"vendorName":"Aliexpress"},{"vendorNo":2,"vendorName":"DHGate"}]}
<tr ng-repeat="item in list" ng-cloak >
  <td>                                    
    <select ng-model="item.vendorNo" 
            ng-options="vendor.vendorName for vendor in vendorList track by vendor.vendorNo"></select>
  </td>
</tr>

When I run this, it generates option value="?" and always selects the option value="?" I know option value="?" is generated when angular cannot find the right value from the list. But it does have a right value in the list which matches with the binding model value and type (integer).

<option selected="selected" value="?"></option>
<option value="1" label="Aliexpress">Aliexpress</option>
<option value="2" label="DHGate">DHGate</option></select>

Can someone please help why it is selecting the value="?" always?

1
  • your ng-options is wrong, it is outputting the object and assigning it to item.vendorNo; you probably just want it to output to item. Commented Jan 19, 2017 at 4:11

2 Answers 2

1

Set vendor.vendorNo as vendor.vendorName inside ng-options

  <td>
    <select ng-model="item.vendorNo" ng-options="vendor.vendorNo as vendor.vendorName for vendor in vendorList" ng-selected="true"></select>{{item.vendorNo}}
  </td>

var csApp = angular.module("app", []);
csApp.controller('expensesCtrl', function($scope, $http) {
  $scope.getExpenses = function() {
    //$http.post('/Home/ExpensesTableList').then(function (response) {
    var response = {
      "csExpenses": [{
        "vendorNo": 1
      }],
      "csVendors": [{
        "vendorNo": 1,
        "vendorName": "Aliexpress"
      }, {
        "vendorNo": 2,
        "vendorName": "DHGate"
      }]
    };
    $scope.vendorList = response.csVendors;
    $scope.list = response.csExpenses;
    //});
  };
  $scope.getExpenses();
});

// returned json
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app" ng-controller="expensesCtrl">
  <table>
    <tr ng-repeat="item in list" ng-cloak>
      <td>
        <select ng-model="item.vendorNo" ng-options="vendor.vendorNo as vendor.vendorName for vendor in vendorList" ng-selected="true"></select>{{item.vendorNo}}
      </td>
    </tr>
  </table>
</div>

Sign up to request clarification or add additional context in comments.

2 Comments

this might work, but it's really not necessary, not a proper use for ng-init, and doesn't really address the actual problem; The OP is likely to see the same unexpected values in selectedItem as they would have in their original model.
@Claies I have corrected my answer. Please check the updated answer. I think setting VendorNo as VendorName will suit for this issue.
1

The syntax of ng-options can be quite confusing, but what is happening in your case is that you are actually outputting the entire object to the ng-model, but your ng-model is set up as if you are only outputting one property.

Breaking down the ng-options a bit more:

vendor.vendorname //sets the text to display in the list
for vendor // sets what gets output for each row
in vendorList // sets what gets iterated
track by vendor.vendorNo //sets the order the list is displayed.

There is an as clause that allows you to output a specific property, but it is generally not necessary. Also, select as and track by are not designed to be used together. https://code.angularjs.org/1.4.7/docs/api/ng/directive/ngOptions

So based on this, instead of setting ng-model="item.vendorNo", you actually want to set ng-model="item"

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

app.controller('MainCtrl', function($scope) {
  var json = {
    "csExpenses": [{
      "vendorNo": 1
    }],
    "csVendors": [{
      "vendorNo": 1,
      "vendorName": "Aliexpress"
    }, {
      "vendorNo": 2,
      "vendorName": "DHGate"
    }]
  }

  $scope.vendorList = json.csVendors;
  $scope.list = json.csExpenses;

  $scope.change = function() {
    console.log($scope.list);
  }

});
<!DOCTYPE html>
<html ng-app="plunker">

<head>
  <meta charset="utf-8" />
  <title>AngularJS Plunker</title>
  <script>
    document.write('<base href="' + document.location + '" />');
  </script>
  <link rel="stylesheet" href="style.css" />
  <script data-require="[email protected]" src="https://code.angularjs.org/1.5.8/angular.js" data-semver="1.5.8"></script>
  <script src="app.js"></script>
</head>

<body ng-controller="MainCtrl">
  <table>
    <tr ng-repeat="item in list" ng-cloak>
      <td>
        <select ng-model="item" ng-change="change()" ng-options="vendor.vendorName for vendor in vendorList track by vendor.vendorNo"></select>
      </td>
    </tr>
  </table>
</body>

</html>

http://plnkr.co/edit/zQPryQvH2zF2YUFFXpU8?p=preview

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.