ng-options not behaving as expected,as documented? - angularjs

No matter what I try, the ID is always passed as the value. I want the Genre.label(string) as the value...
I am trying to get my head around ng-options, i read the docs, and the examples seem straight forward, however I am getting differet results than expected.
my model for Books is
Book: {
title: string,
genre: string,
description: string
}
and my model for Genre is
Genre: {
label: string
description: string
}
then when I use ng-init="getGenres()" to pull genres into my scope, I EXPECT using
ng-options="genre.label for genre in genres track by genre.label"
will use the LABEL for each iteration and populate the option value with the LABEL and as a matter of fact - Inspect Element does show that - it looks like this:
<option label="Sci-fi" value="Sci-fi">Sci-fi</option>
My DATA however ends up looking like this:
_id : 5a2f...5691
genre : "5a2f552765226c3018be9878"
title : "Blah Blah"
Here is the form in context:
<form ng-submit="addBook()" ng-init="getGenres()" >
<div class="form-group" >
<label>Title</label>
<input type="text" class="form-control" ng-model="book.title" placeholder="Title" >
</div>
<div class="form-group" >
<label>Genre</label>
<select class="form-control" ng-model="book.genre"
ng-options="genre.label for genre in genres track by genre.label" >
<option value="">-- choose genre --</option>
</select>
</div>
</form>
Here is the COLTROLLERs getGenres:
// get genres
$scope.getGenres = function() {
$http.get('/api/genres')
.success(function(response) {
$scope.genres = response;
});
}
it returns:
[{
"_id": "5a2f5.....a065b",
"label": "Sci-fi",
"description": "Dealing with subject matter that combines fictional worlds and science, both real and theoretical."
}, {
"_id": "5a2f5.....9877",
"label": "Romance",
"description": "Topics with amorous overtone, undertones and toneless rantings. Matters of the heart. Emotional folly and frolic."
}, {
"_id": "5a2f5.....9878",
"label": "Suspense",
"description": "Events dealing with an arousal of anticipation and dread, mostly in equal parts."
}, {
"_id": "5a2f5.....9879",
"label": "Gobbeldegook",
"description": "nonsensical gibberish. blather, post-moderistic drivel."
}, {
"_id": "5a2f5.....987a",
"label": "Drama",
"description": "Drama Drama Drama Drama Drama Drama Drama"
}, {
"_id": "5a2f5.....987b",
"label": "NonFiction",
"description": "Real life crap. No fakery or literary license, this is REAL!"
}]
Any help is much appreciated
-cheers

you should use like this:
<select class="form-control" ng-model="book.genre"
ng-options="genre.label as genre.label for genre in genres track by genre.label" >
<option value="">-- choose genre --</option>
</select>
If you don't use genre.label as , the genre will be used as the model in this case.
The expression BEFORE as, which is genre.label, will be used as model value.
The expression after as, which is genre.label will be used as displayed value in options.

Related

All Undefined Results

Please tell me if this select statement looks wrong to you. For some reason, every selection in the drop-down reads undefined instead of the username.
View
<select class="form-control" ng-model="filteredUserId" ng-options="users.Id as users.Username for user in users"></select>
Controller
dmUser.GetUsers().then((response) =>
{
$scope.users = response.data;
});
I verified in Postman what the results are. They are list of these kinds of objects:
{
"Id": 123,
"FirstName": "john",
"LastName": "smith",
"Username": "johnsmith",
"EmailAddress": "johnsmith#test.com"
}
I also tried using the following and it actually works...
<select class="form-control" ng-model="filteredUserId">
<option value="0">All</option>
<option ng-repeat="user in users" value="{{user.Id}}">{{user.Username}}</option>
</select>
It's bugging me that the code using the ngOptions doesn't work. What am I missing?

pre select a value using ng-options in angular js [duplicate]

I've seen the documentation of the Angular select directive here: http://docs.angularjs.org/api/ng.directive:select.
I can't figure how to set the default value. This is confusing:
select as label for value in array
Here is the object:
{
"type": "select",
"name": "Service",
"value": "Service 3",
"values": [ "Service 1", "Service 2", "Service 3", "Service 4"]
}
The html (working):
<select><option ng-repeat="value in prop.values">{{value}}</option></select>
and then I'm trying to add an ng-option attribute inside the select element to set prop.value as the default option (not working).
ng-options="(prop.value) for v in prop.values"
What am i doing wrong?
So assuming that object is in your scope:
<div ng-controller="MyCtrl">
<select ng-model="prop.value" ng-options="v for v in prop.values">
</select>
</div>
function MyCtrl($scope) {
$scope.prop = {
"type": "select",
"name": "Service",
"value": "Service 3",
"values": [ "Service 1", "Service 2", "Service 3", "Service 4"]
};
}
Working Plunkr: http://plnkr.co/edit/wTRXZYEPrZJRizEltQ2g
The angular documentation for select* does not answer this question explicitly, but it is there. If you look at the script.js, you will see this:
function MyCntrl($scope) {
$scope.colors = [
{name:'black', shade:'dark'},
{name:'white', shade:'light'},
{name:'red', shade:'dark'},
{name:'blue', shade:'dark'},
{name:'yellow', shade:'light'}
];
$scope.color = $scope.colors[2]; // Default the color to red
}
This is the html:
<select ng-model="color" ng-options="c.name for c in colors"></select>
This seems to be a more obvious way of defaulting a selected value on an <select> with ng-options. Also it will work if you have different label/values.
* This is from Angular 1.2.7
This answer is more usefull when you are bringing data from a DB, make modifications and then persist the changes.
<select ng-options="opt.id as opt.name for opt in users" ng-model="selectedUser"></select>
Check the example here:
http://plnkr.co/edit/HrT5vUMJOtP9esGngbIV
<select name='partyid' id="partyid" class='span3'>
<option value=''>Select Party</option>
<option ng-repeat="item in partyName" value="{{item._id}}" ng-selected="obj.partyname == item.partyname">{{item.partyname}}
</option>
</select>
If your array of objects are complex like:
$scope.friends = [{ name: John , uuid: 1234}, {name: Joe, uuid, 5678}];
And your current model was set to something like:
$scope.user.friend = {name:John, uuid: 1234};
It helped to use the track by function on uuid (or any unique field), as long as the ng-model="user.friend" also has a uuid:
<select ng-model="user.friend"
ng-options="friend as friend.name for friend in friends track by friend.uuid">
</select>
I struggled with this for a couple of hours, so I would like to add some clarifications for it, all the examples noted here, refers to cases where the data is loaded from the script itself, not something coming from a service or a database, so I would like to provide my experience for anyone having the same problem as I did.
Normally you save only the id of the desired option in your database, so... let's show it
service.js
myApp.factory('Models', function($http) {
var models = {};
models.allModels = function(options) {
return $http.post(url_service, {options: options});
};
return models;
});
controller.js
myApp.controller('exampleController', function($scope, Models) {
$scope.mainObj={id_main: 1, id_model: 101};
$scope.selected_model = $scope.mainObj.id_model;
Models.allModels({}).success(function(data) {
$scope.models = data;
});
});
Finally the partial html model.html
Model: <select ng-model="selected_model"
ng-options="model.id_model as model.name for model in models" ></select>
basically I wanted to point that piece "model.id_model as model.name for model in models" the "model.id_model" uses the id of the model for the value so that you can match with the "mainObj.id_model" which is also the "selected_model", this is just a plain value, also "as model.name" is the label for the repeater, finally "model in models" is just the regular cycle that we all know about.
Hope this helps somebody, and if it does, please vote up :D
<select id="itemDescFormId" name="itemDescFormId" size="1" ng-model="prop" ng-change="update()">
<option value="">English(EN)</option>
<option value="23">Corsican(CO)</option>
<option value="43">French(FR)</option>
<option value="16">German(GR)</option>
Just add option with empty value. It will work.
DEMO Plnkr
An easier way to do it is to use data-ng-init like this:
<select data-ng-init="somethingHere = options[0]" data-ng-model="somethingHere" data-ng-options="option.name for option in options"></select>
The main difference here is that you would need to include data-ng-model
The ng-model attribute sets the selected option and also allows you to pipe a filter like orderBy:orderModel.value
index.html
<select ng-model="orderModel" ng-options="option.name for option in orderOptions"></select>
controllers.js
$scope.orderOptions = [
{"name":"Newest","value":"age"},
{"name":"Alphabetical","value":"name"}
];
$scope.orderModel = $scope.orderOptions[0];
If anyone is running into the default value occasionally being not populated on the page in Chrome, IE 10/11, Firefox -- try adding this attribute to your input/select field checking for the populated variable in the HTML, like so:
<input data-ng-model="vm.x" data-ng-if="vm.x !== '' && vm.x !== undefined && vm.x !== null" />
Really simple if you do not care about indexing your options with some numeric id.
Declare your $scope var - people array
$scope.people= ["", "YOU", "ME"];
In the DOM of above scope, create object
<select ng-model="hired" ng-options = "who for who in people"></select>
In your controller, you set your ng-model "hired".
$scope.hired = "ME";
It's really easy!
Just to add up, I did something like this.
<select class="form-control" data-ng-model="itemSelect" ng-change="selectedTemplate(itemSelect)" autofocus>
<option value="undefined" [selected]="itemSelect.Name == undefined" disabled="disabled">Select template...</option>
<option ng-repeat="itemSelect in templateLists" value="{{itemSelect.ID}}">{{itemSelect.Name}}</option></select>

How to set Pre selected data in dynamic select option in IONIC

I face a strange problem where I need to show Pre selected data(which also come from server) in select option. The problem that I need to show select option based on key and value option.
<div class="list list-inset">
<span class="input-label">Permisstion</span>
<select ng-model="permisstion" >
<option ng-repeat="(key, value) in Roles" id="{{key}}" value="{{value}}">{{value}}</option>
</select>
</div>
JSON Data
"Roles": {
"21": "Admin",
"22": "Main Manager",
"23": "Branch Manager",
"26": "Side Manager"
}
I don't no how to show Pre selected data in select option and I try a lot but till now I don't get success.
Please help.
Firt, your JSON is not a array of objects. I dont know if work in a <select> by objects atributes... by my other answer you can do something like in below.
Try to use like that:
"Roles" : {
[
{code: 21, name: "Admin"},
{code: 22, name: "Main Manager"},
{code: 23, name: "Branch Manager"},
{code: 24, name: "Side Manager"}
]
}
So the atribute "code" will be my index to the select:
<select ng-options="role.name for role in Roles track by role.code">
<option value="">They see me rollin</option>
</select>
What I do was use track by role.code, as you can watch in this video.
REMEMBER: If code reapet in the array of objects it will break the <select>.

AnglularJS - ngOptions selected option with string value for the model, but objects as options

Been trawling for hours now trying to understand how this is meant to work.
But effectively I've got
<div class="form-group">
<?php $field = 'member_address_country'; ?>
<label for="<?=$field?>">Country</label>
<select class="form-control" id="<?=$field?>" ng-options="country.country_id as country.country_name for country in countries track by country.country_id" ng-model="a.<?=$field?>">
<option value="" disabled="disabled" selected="selected">-- Select --</option>
</select>
</div>
I've got an array of countries, stored inside $scope.countries as objects looking similar to
[
{country_id: "1", country_name: "england"},
{country_id: "2", country_name: "america"},
{country_id: "3", country_name: "other"},
]
I've got an array of addresses which are in a ngRepeat labeled as a so a.member_address_country is a string, which will contain an int id. in this example its "2"
So although im using ngOptions and track by country.country_id and the value of the model is the id from country_id as expected, when the ngRepeat is rendered it just displays -- Select -- rather than picking the object from the array, based off the tracked id.
What am I doing wrong, and how can I fix this?
I've added a codepen of the issue -> http://codepen.io/owenmelbz/pen/XdxrMO?editors=1010
and another example here ->
angular.module('app', [])
.controller('testController', function($scope) {
$scope.a = {
member_address_country: 100
}
$scope.countries = [{
country_id: 100,
country_name: "england"
}, {
country_id: 200,
country_name: "uk"
}, {
country_id: 300,
country_name: "london"
}]
});
<script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.2/angular.min.js"></script>
<div class="form-group" ng-app="app" ng-controller="testController">
<label for="member_address_country">Country</label>
<select class="form-control" id="member_address_country" ng-options="country.country_id as country.country_name for country in countries track by country.country_id" ng-model="a.member_address_country">
</select>model value is: {{a.member_address_country | json}}
</div>
HTML
<select ng-change="getName(a.member_address_country)" class="form-control" id="member_address_country" ng-options="country.country_id as country.country_name for country in countries" ng-model="a.member_address_country">
</select> model value is: {{a.member_address_country| json}}
Name after change = {{name}};
JS
$scope.a = {
country_id: 100,
country_name: "england"
}
$scope.getName = function(countryid){
angular.forEach($scope.countries,function(data){
if(data.country_id == countryid){
$scope.name = data.country_name;
}
});
};
If I understand you correctly, you are wondering why you are defaulting to the option containing your placeholder text?
<option value="" disabled="disabled" selected="selected">-- Select --</option>
Two things:
You don't need to include that option unless you have it there as a hook for something else.
If you do want to use that, but don't want it to be displayed by defualt (which to be honest would not make a whole lot of sense to me) then remove the selected="selected" attribute.
Update
In that case, I took a look at your example. The person who asked you the question in the comment above is correct. Your variable has two different names: country & countries. Pick one or the other and make them match, and it should be good to go.
See:
You're referencing this variable
country.country_id
But in your scope, you declare
$scope.countries = [
{
country_id: 100,
country_name: "england"
},
{
country_id: 200,
country_name: "uk"
},
{
country_id: 300,
country_name: "london"
}
]
Update 2
I think this is what you want or nearly:
ng-options="country.country_id for country in countries track by id"

Data binding with ng-option dropdown in Angular

I have a dropdown and I want to display a value based on the dropdown selection in Angular. I am using ng-options and figure a simple data binding should work, but the data binding isn't showing up. Here's a plunker: http://plnkr.co/edit/IptAt3e5EZi15OObfWFr?p=preview
<select ng-model="defcom"
ng-options="opt.DefCom as opt.DefCom for opt in acct_info | filter:{Req:'MUST'}:true" >
</select>
<select ng-model="defcust"
ng-options="opt.Customer as opt.Customer for opt in cust_info | filter: {Com: defcom}: true">
</select>
<p>{{ cust_info.Name }}</p>
in the controller:
$scope.cust_info = [
{
"Customer": "1",
"Com": "1",
"Name": "First Name"
},
{
"Customer": "2",
"Com": "1",
"Name": "Second Name"
},
{
"Customer": "3",
"Com": "4",
"Name": "Third Name"
}];
{{cust_info[defcust-1].Name}} should work as expected
In this line:
{{cust_info.Name}}
you are trying to reference Name incorrectly, you have an array of objects which each have Name therefore that will not work.
Change it to:
{{cust_info[defcust - 1].Name}}
-1 because "Customer" starts at 1 and not 0
and you will get the nth index inside cust_info, where the nth index was selected by the user and stored into defcust.
http://plnkr.co/edit/WHkijq8ea0ATnO4JXnc9?p=preview
Without using the index to achieve this needs a little more javascript in there I guess.. I've added some. Hope this helps.. See this demo
<select ng-model="defcom" ng-change="change_acc(defcom)"
ng-options="opt.DefCom as opt.DefCom for opt in acct_info | filter:{Req:'MUST'}:true" >
</select>
<select ng-model="defcust" ng-change="change_cust(defcust)"
ng-options="opt.Customer as opt.Customer for opt in cust_info | filter: {Com: defcom}: true">
</select>
http://plnkr.co/edit/pf6PtOWANfLxulQupqZq?p=preview

Resources