Skip to content
This repository has been archived by the owner on Apr 12, 2024. It is now read-only.

Commit

Permalink
fix(ngOptions): don't throw if options are unset inside writeValue
Browse files Browse the repository at this point in the history
This can happen in the following case:
- there's a blank option inside the select
- another directive on the select element compiles the contents of it before ngOptions is linked.

Now this happens:
- the option directive is compiled and adds an element $destroy listener that calls ngModel.$render
- when ngOptions processes the blank option, it removes the element, and
triggers the $destroy listener
- ngModel.$render delegates to selectCtrl.writeValue, which accesses the options
- in that phase, the options aren't yet set

Fixes #11685
  • Loading branch information
Narretz committed Sep 28, 2015
1 parent e51174b commit c38f876
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 1 deletion.
2 changes: 1 addition & 1 deletion src/ng/directive/ngOptions.js
Original file line number Diff line number Diff line change
Expand Up @@ -453,7 +453,7 @@ var ngOptionsDirective = ['$compile', '$parse', function($compile, $parse) {
if (!multiple) {

selectCtrl.writeValue = function writeNgOptionsValue(value) {
var option = options.getOptionFromViewValue(value);
var option = options && options.getOptionFromViewValue(value);

if (option && !option.disabled) {
if (selectElement[0].value !== option.selectValue) {
Expand Down
23 changes: 23 additions & 0 deletions test/ng/directive/ngOptionsSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,17 @@ describe('ngOptions', function() {
});
});

beforeEach(module(function($compileProvider) {
$compileProvider
.directive('compileContents', function($compile) {
return {
link: function(scope, element) {
$compile(element.contents())(scope);
}
};
});
}));

beforeEach(inject(function($rootScope, _$compile_) {
scope = $rootScope.$new(); //create a child scope because the root scope can't be $destroy-ed
$compile = _$compile_;
Expand Down Expand Up @@ -2119,6 +2130,18 @@ describe('ngOptions', function() {
option = element.find('option').eq(0);
expect(option.text()).toBe('A');
});


it('should not throw when a directive compiles the blank option before ngOptions is linked', function() {
expect(function() {
createSelect({
'compile-contents': '',
'name': 'select',
'ng-model': 'value',
'ng-options': 'item for item in items',
}, true);
}).not.toThrow();
});
});


Expand Down

0 comments on commit c38f876

Please sign in to comment.