Skip to content

Commit 863b61c

Browse files
committed
fix(select): emitting change event twice for reset values
Fixes `mat-select` emitting its change event twice when a reset value is selected, as well as when it's selected twice in a row. This PR covers #10859 which would've introduced another issue. Fixes #10675. Fixes #13579.
1 parent a30094b commit 863b61c

File tree

2 files changed

+61
-1
lines changed

2 files changed

+61
-1
lines changed

src/material/select/select.spec.ts

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3151,6 +3151,63 @@ describe('MatSelect', () => {
31513151
.toBeFalsy('Expected no value after tabbing away.');
31523152
}));
31533153

3154+
it('should emit once when a reset value is selected', fakeAsync(() => {
3155+
const fixture = TestBed.createComponent(BasicSelectWithoutForms);
3156+
const instance = fixture.componentInstance;
3157+
const spy = jasmine.createSpy('change spy');
3158+
3159+
instance.selectedFood = 'sandwich-2';
3160+
instance.foods[0].value = null;
3161+
fixture.detectChanges();
3162+
3163+
const subscription = instance.select.selectionChange.subscribe(spy);
3164+
3165+
fixture.debugElement.query(By.css('.mat-select-trigger')).nativeElement.click();
3166+
fixture.detectChanges();
3167+
flush();
3168+
3169+
(overlayContainerElement.querySelector('mat-option') as HTMLElement).click();
3170+
fixture.detectChanges();
3171+
flush();
3172+
3173+
expect(spy).toHaveBeenCalledTimes(1);
3174+
3175+
subscription.unsubscribe();
3176+
}));
3177+
3178+
it('should not emit the change event multiple times when a reset option is ' +
3179+
'selected twice in a row', fakeAsync(() => {
3180+
const fixture = TestBed.createComponent(BasicSelectWithoutForms);
3181+
const instance = fixture.componentInstance;
3182+
const spy = jasmine.createSpy('change spy');
3183+
3184+
instance.foods[0].value = null;
3185+
fixture.detectChanges();
3186+
3187+
const subscription = instance.select.selectionChange.subscribe(spy);
3188+
3189+
fixture.debugElement.query(By.css('.mat-select-trigger')).nativeElement.click();
3190+
fixture.detectChanges();
3191+
flush();
3192+
3193+
(overlayContainerElement.querySelector('mat-option') as HTMLElement).click();
3194+
fixture.detectChanges();
3195+
flush();
3196+
3197+
expect(spy).not.toHaveBeenCalled();
3198+
3199+
fixture.debugElement.query(By.css('.mat-select-trigger')).nativeElement.click();
3200+
fixture.detectChanges();
3201+
flush();
3202+
3203+
(overlayContainerElement.querySelector('mat-option') as HTMLElement).click();
3204+
fixture.detectChanges();
3205+
flush();
3206+
3207+
expect(spy).not.toHaveBeenCalled();
3208+
3209+
subscription.unsubscribe();
3210+
}));
31543211

31553212
});
31563213

src/material/select/select.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -966,7 +966,10 @@ export class MatSelect extends _MatSelectMixinBase implements AfterContentInit,
966966
if (option.value == null && !this._multiple) {
967967
option.deselect();
968968
this._selectionModel.clear();
969-
this._propagateChanges(option.value);
969+
970+
if (this.value != null) {
971+
this._propagateChanges(option.value);
972+
}
970973
} else {
971974
if (wasSelected !== option.selected) {
972975
option.selected ? this._selectionModel.select(option) :

0 commit comments

Comments
 (0)