I have a <select>
with an ng-model
. I want the values of my <option>
s to be JSON objects.
When a user selects an option, I want to display individual properties from the selected object.
I have the following plunker showing what I am trying to achieve.
<div ng-controller="myCtrl as vm">
<div>
Person:
<select ng-model="vm.person">
<option value='{"name": "Matt", "age": "21"}'>Matt</option>
<option value='{"name": "John", "age": "22"}'>John</option>
</select>
</div>
<br>
Person: <input type="text" ng-model="vm.person">
Name: <input type="text" ng-model="vm.person.name">
Age: <input type="text" ng-model="vm.person.age">
</div>
The issue is that vm.person
is a string, not an object, so I cannot access properties of it.
I have tried fromJson but that throws an error because it is non assignable (which is sensible).
<input type="text" ng-model="angular.fromJson(vm.person.name)">
I could watch for a change on vm.person
, then do an angular.fromJson
there, but that doesn't feel right. It feels like there is a better way.
I essentially want to parse the string before it gets to the model, so that by the time it get's to the model, it is a javascript object. This will allow me to access properties of that object.
What is the correct way to handle this in angular?
If there is no "angular" way, what is the common way to handle this in Javascript?
EDIT
A forked plunker to show the effects of adding a $scope.$watch
.
function myCtrl($scope){
var vm = this;
$scope.$watch('vm.person', function(){
vm.person = angular.fromJson(vm.person);
})
}
This allows the Name and Age inputs to be populated correctly, but it breaks the select (it isn't populated by the selected value anymore because the model is changed).
How about using ng-options, You can pass the object from the controller
and then have the select on the basis of that.
HTML:
<div ng-controller="myCtrl as vm">
<select ng-options="selected.name for selected in vm.person" ng-model="vm.customPerson">
<option value="" disabled>Person</option>
</select>
<br>
<br>
Person: <input type="text" ng-model="vm.customPerson">
<br>
Name: <input type="text" ng-model="vm.customPerson.name">
<br>
Age: <input type="text" ng-model="vm.customPerson.age">
</div>
JS:
var app = angular.module('app', []);
app.controller('myCtrl',
function($scope){
this.person=[
{name: 'Matt', age: '12'},
{name: 'John', age: '23'},
];
});
I hope the following Plunker satisfies what you are intending to get.