Skip to content

Commit 1dad2a8

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 d22f48c commit 1dad2a8

File tree

2 files changed

+62
-1
lines changed

2 files changed

+62
-1
lines changed

src/lib/select/select.spec.ts

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2877,6 +2877,64 @@ describe('MatSelect', () => {
28772877
expect(spy).toHaveBeenCalledWith('steak-0');
28782878
}));
28792879

2880+
it('should emit once when a reset value is selected', fakeAsync(() => {
2881+
const fixture = TestBed.createComponent(BasicSelectWithoutForms);
2882+
const instance = fixture.componentInstance;
2883+
const spy = jasmine.createSpy('change spy');
2884+
2885+
instance.selectedFood = 'sandwich-2';
2886+
instance.foods[0].value = null;
2887+
fixture.detectChanges();
2888+
2889+
const subscription = instance.select.selectionChange.subscribe(spy);
2890+
2891+
fixture.debugElement.query(By.css('.mat-select-trigger')).nativeElement.click();
2892+
fixture.detectChanges();
2893+
flush();
2894+
2895+
(overlayContainerElement.querySelector('mat-option') as HTMLElement).click();
2896+
fixture.detectChanges();
2897+
flush();
2898+
2899+
expect(spy).toHaveBeenCalledTimes(1);
2900+
2901+
subscription.unsubscribe();
2902+
}));
2903+
2904+
it('should not emit the change event multiple times when a reset option is ' +
2905+
'selected twice in a row', fakeAsync(() => {
2906+
const fixture = TestBed.createComponent(BasicSelectWithoutForms);
2907+
const instance = fixture.componentInstance;
2908+
const spy = jasmine.createSpy('change spy');
2909+
2910+
instance.foods[0].value = null;
2911+
fixture.detectChanges();
2912+
2913+
const subscription = instance.select.selectionChange.subscribe(spy);
2914+
2915+
fixture.debugElement.query(By.css('.mat-select-trigger')).nativeElement.click();
2916+
fixture.detectChanges();
2917+
flush();
2918+
2919+
(overlayContainerElement.querySelector('mat-option') as HTMLElement).click();
2920+
fixture.detectChanges();
2921+
flush();
2922+
2923+
expect(spy).not.toHaveBeenCalled();
2924+
2925+
fixture.debugElement.query(By.css('.mat-select-trigger')).nativeElement.click();
2926+
fixture.detectChanges();
2927+
flush();
2928+
2929+
(overlayContainerElement.querySelector('mat-option') as HTMLElement).click();
2930+
fixture.detectChanges();
2931+
flush();
2932+
2933+
expect(spy).not.toHaveBeenCalled();
2934+
2935+
subscription.unsubscribe();
2936+
}));
2937+
28802938
});
28812939

28822940
describe('with option centering disabled', () => {

src/lib/select/select.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -930,7 +930,10 @@ export class MatSelect extends _MatSelectMixinBase implements AfterContentInit,
930930
if (option.value == null && !this._multiple) {
931931
option.deselect();
932932
this._selectionModel.clear();
933-
this._propagateChanges(option.value);
933+
934+
if (this.value != null) {
935+
this._propagateChanges(option.value);
936+
}
934937
} else {
935938
option.selected ? this._selectionModel.select(option) : this._selectionModel.deselect(option);
936939

0 commit comments

Comments
 (0)