How to set the ng-options default using object? - angularjs

If i set a value dropdown value as a object is not working as expected.
for Example :
HTML:
<select ng-model="selected" ng-options="lst as lst.name for lst in list"></select>
JS:
$scope.list=[{'name':'Person-1','age':23},
{'name':'Person-2','age':14},
{'name':'Person-3','age':32},
{'name':'Person-4','age':34},
{'name':'Person-5','age':67},
{'name':'Person-6','age':12}];
$scope.selected = {'name':'Person-3','age':32};
If i assign a value as $scope.selected = $scope.list[0] is working fine. But now how can i assign a object to select.
i have attached the plunker link : http://plnkr.co/edit/WJo0W688s5NDN7kZYOPR?p=preview

It's because the object which you are assigning is not there in $scope.list. However it looks same but it's a different object. $scope.list[0] is working because it points to the same object reference which $scope.list is having.
See updated plunker so that you can understand.
Updated
If you have objects then you need to iterate over the $scope.list by comparing properties and find index of appropriate object and use that index to assign selected object like.
$scope.selected = $scope.list[matchIndex]

$scope.selected = $scope.list[0];
This is how you set the default option

Related

AngularJS ngOptions track by does not set entire object to ngModel

Here my json object :
$scope.todos = [{
name: 'angular',
field: ['a', 'b', 'c', 'd'],
id: 1
}, {
name: 'asd',
field: ['a', 'b', 'c', 'd', 'e'],
id: 2
}];
I give select as :
<select ng-model="dashboard.type" ng-options="item as item.name for item in todos track by item.name"></select>
Now when an option is chosen i want another select which iterates upon ngModel of previous select. The next looks like :
<select ng-model="dashboard.label" ng-options="item as item for item in dashboard.type.field"></select>
It works fine when i choose the option manually but when their is a value in dashboard.type (eg: $scope.dashboard.type.name = 'qwe') in my script, it uses track by to choose the option and save it in dashboard.type, instead of saving the entire object it just saves the value used in track by option.
Value for dashboard.type:
when i choose option manually :
{"name":"qwe","field":["a","b","c","d","f"],"id":3}
When track by is used :
{"name":"qwe"}
NOTE: I cannot use track by item . It has to be a property of the object item. It can either be name or id.
Here's a plnkr.
Edit :
As pointed out by many, i would like to clarify that I can not initialise the object to any value of todos list. This is because dashboard.type.name value would be different every single time and todos list vary from 10 to 100's of objects. Now I have to iterate the list todos check if todos[index].name==someName and assign the relevant object. I am actively trying to avoid this soution (because there has to be a better way).
NOTE : I also tried using ng-change and assign the actual object to dashboard.type.name but that works only when option is selected manually ,which already seems to be working fine. It does not assign the object when track by is used.
IMPORTANT: $scope.dashboard.type.name = 'qwe' is just an example. Value of $scope.dashboard.type.name may change every single time the page is loaded.
PS: Also i should have mentioned this earlier.Sorry, My bad!
This issue is not because of track by. Setting a default value by doing $scope.dashboard.type.name = 'qwe', causes ng-model to look like $scope.dashboard.type = {name : 'qwe'}. Instead of selecting the default value this way, you should use $scope.dashboard.type = $scope.todos[2];. This will make sure the entire object is set to $scope.dashboard.type.
Edited plunker
To initialize the modal by a default value you can use ng-init. For example
<select ng-init="dashboard.type = todos[2]" ng-model="dashboard.type" ng-options="item as item.name for item in todos track by item.name">
</select>
call this function on ng-init
in html
ng-init ="initialize();"
in js
$scope.dashboard={};//initialize object
$scope.dashboard.type ={}//initialize object
$scope.initialize =function(){
//no need to iterate if it is certain that your Id and index is always same suppose your initial id is 3
//then
var currId =3;//suppose initial id is there
$scope.dashboard.type =$scope.todos[currId]
}
here is codepen for it
http://codepen.io/vkvicky-vasudev/pen/MeexmK

AngularJS dropdown selected values need as JSON

I have multiple dropdowns in my application which are populating through a json (which is a map basically) given in controller.
For first dropdown if I select xyz value, then corresponding xyz1 values should come in dropdown and similarly for third dropdown. This all is happening fine currently. But now I want these user selected values to get in json form so that I can send back to backend for further processing. I am not getting selected values but the wrong second dropdown values if I print on console.
codepen and
working plunker
I understand that you need to get values from the dynamic input elements. For that, you need to set ng-model to the input elements, not to the div.
The below updated part would help.
<div ng-init="pageObjectName.pageObjParam={}" ng-repeat="(key , value) in pageObjectName.pageObjMethod">
<input ng-model='pageObjectName.pageObjParam[key]' value='' placeholder="{{key}} - {{value}}"></input>
</div>
Now you can get those values from $scope.pageObjectName.pageObjParam.
Updated Plunker
EDIT
I hope the above part helped to get value from dynamic input fields. Now I suggest you to update the code block like below to get the selected values from dropdown (ie, use one hidden input field for each select) and you will get what you want.
<select id="pageObj" ng-model="pageObjectName.pageObj" ng-options="key for (key,value) in pageData" ng-change="pageObjectName.pageObjParam.pageObj=pageObjectName.pageObj">
<option value=''>Select Page Object</option>
</select>
<input ng-model='pageObjectName.pageObjParam.pageObj' hidden/>
You can have a look at the same plunker now
Your codepen seems to be confusing and not working. As you already have the implemention for dropdown I will continue from here about how to get the data from the drop down and convert the data into a JSON.
After getting the data from the dropdown create a JSON object and store it.
I have written a small example to show how to store the data.
$scope.selectedState = function(item) {
var output = {};
output.name = item.name;
$scope.viewOutput = output;
};
Update:
I tried hard but could not get the values using angular way. If you are still looking for an answer then we can use basic javascript way. Refer plunker for the same.
$scope.submitMyForm = function() {
/* while compiling form , angular created this object*/
var pgObj = $scope.pageObj;
var pgClass = $scope.pageClass;
var pgMethod = $scope.pageObjMethod;
var pgObjvalue = document.getElementById('pageObj').value;
var pgClassvalue = document.getElementById('pageClass').value;
var pgMethodvalue = document.getElementById('pageMethod').value;
$scope.output = {'object' : pgObjvalue, 'class': pgClassvalue, 'method': pgMethodvalue};
console.log(data);
};
Working Plunker.
P.S: If you figured out the answer using angular way then do let me know after posting it in the answer section.

ng-model and ng-options not matching up?

I have a method in my resources object that comes in as:
resources.type
otherstuff: 'more strings'
type:'specifictype'
morestuff: 'morestuff'
The user can change this type with a dropdown / through another call that gets a list of all possible types which looks like resourceList.types which has a list of objects like this json
types:
[
{name:'resourcetype1'},
{name:'resourcetype2'},
etc...
],
my html looks like:
<select ng-model="resources.type" ng-options="name.name for name in resourceList.types">
</select>
The select/drop down box populates with my resourceList.type stuff but when the page loads the ng-model doesn't set to the already selected resource type. It actually selects a blank entry at the top of the drop down when you click. Is angular picky about this? How can I get the ng-model to behave the way I want it to?
I tried messing around with ng-options with the different ways of getting the repeat but I feel like this is more how angular connects the model. Does it just match the string to the ng-options list?
Here's the plnkr as you can see it's not defaulting to type1
http://plnkr.co/edit/NyWACtFQuyndR6CG8lpN?p=info
In Angular, the model is the single source of truth.
This means that if you want a value selected (and bound to your ngModel) you need to assign it to the model:
<select ng-model="resources.type"
ng-options="type.name as type.name for type in resourceList.types">
</select>
$scope.resources = {...};
$scope.resourceList = {
...
types: [
{name: 'resourcetype1'},
{name: 'resourcetype2'},
...
]
};
// Set the model to the desired value
$scope.resources.type = $scope.resourceList.types[0].name;
See, also, this short demo.
You don't have to set your model's value to the reference object in resourceList. In fact, the accepted answer works fine without this line:
$scope.resources.type = $scope.resourceList.types[0].name;
How is it working? Thanks to the "as" notation in the ngOptions. Without the "as", the match is made on the full type element, which is an object, so the match is made on the reference's object, not the name's value.
With the "as" the match is made on the element's property, name.
I've forked the plunker: http://plnkr.co/edit/kORfxGdsWBUlFWHXp6Ry?p=preview
in my case it didnt work since ngOptions was an array of integers and i was trying to set ngModal to string type (2the year 2014).
the solution is simple: parseInt function

Programmatically selecting ng-options bound to object data source

I have an ng-options select bound to an object. Setting the ng-model programmatically only works properly (updates the select) when setting it as a string. If I set the ng-model as an integer, it doesn't work. I really don't want to have to make this conversion. Is this the only way?
http://jsfiddle.net/HMjnV/1/
<div ng-controller="MyCtrl">
<select ng-options="id as name for (id, name) in items" ng-model="selected"></select>
<div>Selected ID: {{selected}} </div>
<button ng-click="setSelected(1)">Set Selected to ID 1 as Integer</button>
<button ng-click="setSelected('1')">Set Selected to ID 1 as String</button>
<div>Programmatically setting the ng-model as string sets the dropdown but not as integer.</div>
</div>
var myApp = angular.module('myApp',[]);
function MyCtrl($scope) {
$scope.items = {1: 'a', 2: 'b', 3:'c'};
$scope.selected = null;
$scope.setSelected = function(id) {
$scope.selected = id;
}
}
EDITED
You might try using toString when you programmatically set the model value, if you're looking for a quick and dirty solution. See #ExpertSystems answer for detail on the core of the problem.
$scope.setSelected = function(id) {
$scope.selected = id.toString();
}
This is odd, but you can get the binding between ng-options and ng-model to work by forcing a cast to occur in the comprehension expression:
ng-options="id*1 as name for (id, name) in items"
Here is a fork of your fiddle demonstrating this trick: http://jsfiddle.net/wittwerj/HMjnV/9/
Having said that, I do prefer Marc's approach of converting toString in the controller.
Yes to pre-populate the value like you have done then definitely it should be a string. Since the value attribute in option tag takes only String. But yes in AngularJs you can give references like this given in the fiddle . And the workaround to your problem will be converting id to string.
JS Objects have property name-value pairs.
value can be of any type, but name is always a string.
Although you think you define it as a number, it is automatically converted to string.
There is no way you can change that (i.e. create an object with number property-names).

ng-options predefined option Object

Have a look at my example
http://plnkr.co/edit/21ewxVIaRm4IHyF3TgoD?p=preview
I need the option object to be stored as ng-model so i use for ng-options ng-options="m as m.name for m in list"
However, if i set ng-model manually as the object it does not select the correct option in the dropdown list by default. It stores the data correctly, but it only pre-selects an option if use this expression ng-options="m.name as m.name for m in list" but this stores a string on the model instead of the options object.
Am I doing something incorrectly?
Goal:
set ng-model to the default option object and have it be automatically selected in the dropdown.
Updated plunker.
For the version you are using (1.0.8), you would have to resolve the object using a loop:
$scope.selected = {
name:"Something"
}
$scope.setSelected = function() {
angular.forEach($scope.list, function(item) {
if (item.name == $scope.selected.name) {
$scope.selected = item;
}
})
}
$scope.setSelected();
More recent versions, have track by syntax supported in the ng-options. So you could write:
ng-options="m.name for m in list track by m.name"
And this would set the object that matches the predicate.
As Davin Tryon has already mentioned, using track by is the correct way of doing it, however, I see some people using track by and 'as' in the same ng-options string, which will not work. using track by should also cater the need of using 'as'

Resources