WakaChewbacca WakaChewbacca - 3 months ago 16
Javascript Question

ng-model is setting JavaScript object property to array

I have an angular controller with a temporary JavaScript object

currentExpense
, an object constructor
TestExpense
, and array
TestExpenses
to which newly created
TestExpense
objects will be pushed via a function
submitExpenses
. The code for these is as follows:

$scope.currentExpense = {
employeeId: 9,
date: '',
account: '',
task: '',
expenseType: '',
expenseCategory: '',
notes: '',
amount: ''
};

function TestExpense(employeeId, date, account, task, expenseType,
expenseCategory, notes, amount) {
this.employeeId = employeeId;
this.date = date;
this.account = account;
this.task = task;
this.expenseType = expenseType;
this.expenseCategory = expenseCategory;
this.notes = notes;
this.amount = amount;
}

$scope.TestExpenses = [];

$scope.submitExpenses = function () {
$scope.TestExpenses = [];
$scope.TestExpenses.push(
new TestExpense(
$scope.currentExpense.employeeId,
$scope.currentExpense.date,
$scope.currentExpense.account,
$scope.currentExpense.task,
$scope.currentExpense.expenseType,
$scope.currentExpense.expenseCategory,
$scope.currentExpense.notes,
$scope.currentExpense.amount
)
);
console.log($scope.TestExpenses);
};


One usage of
ng-model
in my view is as follows:

<select multiple="" class="form-control" ng-model="currentExpense.expenseType"
ng-options="task.expenseTypeId as task.expenseTypeTitle for task in ExpenseTypes" required>
</select>


And here are the relevant
ExpenseType
constructor and
ExpenseTypes
array:

function ExpenseType(expenseTypeId, expenseTypeTitle) {
this.expenseTypeId = expenseTypeId;
this.expenseTypeTitle = expenseTypeTitle;
}

$scope.ExpenseTypes = [];


My problem is that upon logging the objects in the
TestExpenses
array, I am seeing arrays for the
expenseType
property:

TestExpense
account:"a"
amount:""
date:""
employeeId:9
expenseCategory: Array[1]
0: 2
length:1
__proto__:Array[0]
expenseType:Array[1]
0:4
length:1
__proto__:Array[0]
notes:""


My goal is to have the
expenseType
property simply be
4
instead of the array it currently is being set to.

Any advice for how to accomplish this is most welcome!

Answer

The problem is here.You can select more than 1 item in the select. So it will push the more items in the expenseType.

But for one item you can add some logic here

var expenseType =  $scope.currentExpense.expenseType.length === 1 ? $scope.currentExpense.expenseType[0] : $scope.currentExpense.expenseType;

and then pass expenseType to your constructor;

angular.module('myApp',[]).controller('MyCtrl', ['$scope', function($scope){
  
$scope.currentExpense = {
       employeeId: 9,
       date: '',
       account: '',
       task: '',
       expenseType: '',
       expenseCategory: '',
       notes: '',
       amount: ''
   };
  
  $scope.TestExpenses = [];
  
  $scope.ExpenseTypes = [
     new ExpenseType(1, 'First'),
    new ExpenseType(2, 'Second'),
    new ExpenseType(3, 'Third'),
  ];

$scope.submitExpenses = function () {
    
    var expenseType =  $scope.currentExpense.expenseType.length === 1 ? $scope.currentExpense.expenseType[0] : $scope.currentExpense.expenseType;
    
    $scope.TestExpenses.push(
        new TestExpense(
        $scope.currentExpense.employeeId,
        $scope.currentExpense.date,
        $scope.currentExpense.account,
        $scope.currentExpense.task,
        expenseType,
        $scope.currentExpense.expenseCategory,
        $scope.currentExpense.notes,
        $scope.currentExpense.amount
        )
    );
    console.log($scope.TestExpenses);
};
  
  

}])

function TestExpense(employeeId, date, account, task, expenseType,
                                     expenseCategory, notes, amount) {
    this.employeeId = employeeId;
    this.date = date;
    this.account = account;
    this.task = task;
    this.expenseType = expenseType;
    this.expenseCategory = expenseCategory;
    this.notes = notes;
    this.amount = amount;
}

function ExpenseType(expenseTypeId, expenseTypeTitle) {
    this.expenseTypeId = expenseTypeId;
    this.expenseTypeTitle = expenseTypeTitle;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app='myApp' ng-controller='MyCtrl'>
  <select multiple="" class="form-control" ng-model="currentExpense.expenseType" ng-click='submitExpenses()' size='3'
 ng-options="task.expenseTypeId as task.expenseTypeTitle for task in ExpenseTypes" required>
  </select>
  </div>