Adding ng-model:"foo" to a prepopulated select element results in an additional "undefined" option being added and removes the effect of select:"select".
The HTML:
<select ng-model="foo" ng-app >
<option value="1">1</option>
<option selected="selected" value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
<option value="5">5</option>
</select>
Becomes:
<select ng-model="foo" ng-app >
<option value="? undefined:undefined ?"></option>
<option value="1">1</option>
<option selected="selected" value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
<option value="5">5</option>
</select>
In the example above the first option value="? undefined:undefined ?" is selected instead of the expected option value="2".
Reproduced at http://jsfiddle.net/K8rSu/
Hello
I have encountered the same issue.
I cannot set a default selected item when using ng-model directive with select element.
A workaround could be to set the value of the foo object in the controller side.
$scope.foo = '2';
Had the same issue.
The work around doesn't work for me.
Hi Folks,
I am using v1.0.1 and I still encounter the same problem, is there any update about this issue ?
it's a feature, not a bug
Anyone as a solution ? I have the same bug...
Guys, this is not a bug. The select element is bind to model field, which data is undefined. What value select should display? Yes, undefined. You try to pass data via markup, it is not an Angular way.
Just keep your data in JS model, not in HTML markup.
Agree with @appetito, this is _not_ a bug as far as I can tell. There is a similar question with an answer on SO:
http://stackoverflow.com/questions/12654631/why-does-angularjs-include-an-empty-option-in-select
As commented by other people this happens when a value is asigned in the model that isn't an option in the select. So it's developers fault. But I also think current behaviour is not good. Data inconsistency happens, regardsless we like it or not, so we have to find ut the best way to deal with it.
Currently if a nonexistant value is assigned Angular adds more inconsistency, it adds a nonexistant option to the select (usually "? string:undefined ?", "? undefined:undefined ?" or "?") so now we have two values that doesn't exist, instead of one. A good behaviour would be adding the nonexistant option to the select or not adding anything. That would be much better than the current behaviour, because of it would keep or mitigate data inconsistency instead of increasing it.
In my case, I solved it by putting the select element inside the ng-controller related to it.
As already commented by many people this works as intended. Closing for now, please reopen if need.
@pkozlowski-opensource I think there is room for improvement, especially when using together with ngSelected:
<select ng-model="foo" ng-app >
<option value="1">1</option>
<option ng-selected="true" value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
<option value="5">5</option>
</select>
In this case I believe it is very explicit that the developer is expecting $scope.foo === 2 after the initial page loading is completed.
If you really really want to do this, just ng-init your model. You're already doing one thing in a non-Angular way, so you might as well do two.
<select ng-model="foo" ng-app ng-init="foo='2'">
I tried everything and only this is working.
<select ng-init="person='1'" ng-model="person">
I have a case where I'm loading data for the selects over $http building the list of options by ng-repeat ... however, when I try to assign the model a value after getting the data over $http, angular still adds a new value saying either number:X or string:X .... I want to set a custom value for the model on building the data (because I don't know that value beforehand)
something like the following snippet doesn't always work!
Foos.get().success(function(data){
$scope.foos = data.foos;
$scope.foo = parseInt(data.foos[0].id);
}
though on the HTML side I have it say
<select ng-model="foo">
<option value="all">all</option>
<option ng-repeat="foo in foos" ng-value="foo.id">{{ foo.name }}</option>
</select>
Yes even i had this problem, for me it was'nt the assigning the values on load, i used a simple empty value like
<option value="">--Select--</option>
So now the select will by default will have this select option as set in case no value exists and your js checks if value empty will also not be harmed 'cause the value selected is empty and your error is triggered.
Not sure if this is helpful but just my 2 cents
done!!
@pkozlowski-opensource Same problem, I think ? undefined:undefined ? should not be set as value. When a user choose nothing the ? undefined:undefined ? will be submitted as value.
I tried this and it worked,
I think that my problem with all of this is when you are rendering the select via PHP / Twig templates then allowing AngularJS to take over afterwards.
Why can't I just tell AngularJS to select based on the index of the option regardless of value?
@trisweb , this is work for me.
@trisweb :+1:
the same problem
sometimes I get this
other times I get this
Agree with @itsmechlark comment
I just came into this problem as well. @itsmechlark has a good point. Framework should not provide a selected option if none is provided within Angular. "? undefined:undefined ?" just seems irresponsible from the framework.
This worked for me.
<select ng-model="foo" ng-init="foo='1' ">
<option ng-selected="true" value="1">1</option>
<option value="1">1</option>
<option value="3">3</option>
</select>
Agree with @eyeamaman
I run across the same problem too,
the option value is generated by php script
<?php while ($row = $options->fetch_array()) { ?>
<option><?= $row['title']?></option>
<?php }?>
I don't think I can use ng-init="foo='1' to set default value ,cause I don't know the value in advance.
@robinclark007, it's a workaround (for a not-really-supported usecase), but you could try setting ngInit on the selected option. (You should know the value by then, right ?).
This can be a huge pain with traditional CMS work where you want to rely on the server for a lot of data (and not create a webservis for every bit of it) but still use angular. Here is a small directive to use in the place of ng-model, which will set your model's initial value based on the static markup (value, selected, etc) https://github.com/vespoli/init-model
I wrote a workaround for this issue in the form of a directive: https://gist.github.com/Tobiaqs/97fba556349281f2db90
Include ts-select-fix in your app dependencies.
<select ng-model="data.kindOfCheese">...</select>
becomes
<select ts-select-fix ng-model="data.kindOfCheese">...</select>
This directive allows you to:
Plunker demonstrating the effect:
https://plnkr.co/edit/TCaqT1Kr37b1jQyyRSyv?p=preview
EDIT: I just found out that setting the properties in the model as string instead of a number (partially) fixes the problem
Using 'ng-selected="true' on the option tag I wanted to show as selected worked for me (referring to gsklee's comment from 3rd September 2013)
I found the answer!!!
html:
<select id="buggySelect" ng-model="foo" ng-app >
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
<option value="5">5</option>
</select>
css:
display:none;
}
js controller:
$scope.foo = "2";
this will remove the blank option and point it back to the correct place.
@Fierfek Brilliant. Thanks mate.
This happens even when the initial value is defined and is a valid option.
HTML
<select ng-model='itemIndex' ng-init='itemIndex = 0'>
<option value='{{$index}}' ng-repeat='item in lists.items' ng-selected='$parent.itemIndex === $index'>{{$index + 1}}</option>
</select>
I've tested this with and without the ngInit.
Controller
$scope.itemIndex = 0; // Initialized here even though using ng-init in the HTML.
Oddly enough, this same code works later on the page for another <select> element. The only difference is the index variable name and the list of items I repeat over (e.g. `ng-repeat='item in itemList``). Everything is initialized the same way.
@c1moore, if you think this is a different problem, please open a new issue and provide a runnable demo (e.g. using CodePen, Plnkr etc).