fix(forms): correct usage of `selectedOptions` (#37620)

Previously, `registerOnChange` used `hasOwnProperty` to identify if the
property is supported. However, this does not work as the `selectedOptions`
property is an inherited property. This commit fixes this by verifying
the property on the prototype instead.

Closes #37433

PR Close #37620
This commit is contained in:
Sonu Kapoor 2020-06-17 06:50:43 -04:00 committed by Andrew Kushnir
parent 77b62a52c0
commit e36d5b201a
2 changed files with 13 additions and 1 deletions

View File

@ -156,7 +156,7 @@ export class SelectMultipleControlValueAccessor implements ControlValueAccessor
registerOnChange(fn: (value: any) => any): void { registerOnChange(fn: (value: any) => any): void {
this.onChange = (_: any) => { this.onChange = (_: any) => {
const selected: Array<any> = []; const selected: Array<any> = [];
if (_.hasOwnProperty('selectedOptions')) { if (_.selectedOptions !== undefined) {
const options: HTMLCollection = _.selectedOptions; const options: HTMLCollection = _.selectedOptions;
for (let i = 0; i < options.length; i++) { for (let i = 0; i < options.length; i++) {
const opt: any = options.item(i); const opt: any = options.item(i);

View File

@ -499,6 +499,18 @@ import {dispatchEvent} from '@angular/platform-browser/testing/src/browser_util'
} }
}; };
it('verify that native `selectedOptions` field is used while detecting the list of selected options',
fakeAsync(() => {
if (isNode || !HTMLSelectElement.prototype.hasOwnProperty('selectedOptions')) return;
const spy = spyOnProperty(HTMLSelectElement.prototype, 'selectedOptions', 'get')
.and.callThrough();
setSelectedCities([]);
selectOptionViaUI('1: Object');
assertOptionElementSelectedState([false, true, false]);
expect(spy.calls.count()).toBe(2);
}));
it('should reflect state of model after option selected and new options subsequently added', it('should reflect state of model after option selected and new options subsequently added',
fakeAsync(() => { fakeAsync(() => {
if (isNode) return; if (isNode) return;