Search code examples
angularjsng-optionsangularjs-ng-change

send the option object when using angularjs ng-options and ng-change


I having an array of objects which I am passing to the ng-options,the array contains objects of currencies in the next pattern:

[{
        "cur_iso": "ILS",
            "cur_symbol": "\u20aa",
            "cur_name_he": "\u05e9\u05e7\u05dc",
            "cur_rate_in_nis": "1.0000",
    }, {
        "cur_iso": "USD",
            "cur_symbol": "$",
            "cur_name_he": "\u05d3\u05d5\u05dc\u05e8",
            "cur_rate_in_nis": "3.8580"
    }]

I am using ng-options to make a select from this array.

<select ng-model="bindCurrencyModel" ng-init="bindCurrencyModel='ILS'" 
ng-options="currency.cur_iso as currency.cur_symbol+' '+currency.cur_name_he for currency in currencies track by currency.cur_iso" 
                    ng-change="setCurrency(currency)">
</select>   

when user is changing the selection I want to update 2 fields: bindCurrencyModel with the cur_iso value and bindRateModel with the cur_rate_in_nis value.

so I had created the next method:

            $scope.setCurrency=function(currency){
                $scope.bindRateModel=parseFloat(currency.cur_rate_in_nis);
            };

the and set ng-change="setCurrency(currency)" but the problem is I am getting:

   TypeError: Cannot read property 'cur_rate_in_nis' of undefined

another strange behavior is empty line I am getting in the beginning of the select.

to see all the code I had created a fiddle....

http://jsfiddle.net/d9esbgjf/5/

THANKS!


Solution

  • The short version is as follows:

    Change your <select> markup to the following:

    <select ng-model="selectedCurrency" ng-init="selectedCurrency=currencies[0]" 
        ng-options="currency as currency.cur_symbol+' '+currency.cur_name_he for currency in currencies track by currency.cur_iso" 
        ng-change="setCurrency(selectedCurrency)">
    </select>
    

    Change your $scope.setCurrency() method to the following:

    $scope.setCurrency = function (currency) {
        $scope.bindRateModel = parseFloat(currency.cur_rate_in_nis);
        $scope.bindCurrencyModel = currency.cur_iso;
    };
    

    Why does this work?

    The first difference is that I am binding the whole currency object to a new selectedCurrency scope property. This gives you access to the whole object, not just the cur_iso property. This saves you having to look through the currencies array to find the full object.

    Then I changed the ng-change expression to pass in this whole object to $scope.setCurrency using the scope property that it is bound to. This allows that method access to the full object.

    Finally, you need to set $scope.bindCurrencyModel inside the $scope.setCurrency() function, so that it will equal just the field that you are interested in.