Skip to content

Commit 55dbbf4

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 e9466a4 commit 55dbbf4

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
@@ -2853,6 +2853,64 @@ describe('MatSelect', () => {
28532853
expect(spy).toHaveBeenCalledWith('steak-0');
28542854
}));
28552855

2856+
it('should emit once when a reset value is selected', fakeAsync(() => {
2857+
const fixture = TestBed.createComponent(BasicSelectWithoutForms);
2858+
const instance = fixture.componentInstance;
2859+
const spy = jasmine.createSpy('change spy');
2860+
2861+
instance.selectedFood = 'sandwich-2';
2862+
instance.foods[0].value = null;
2863+
fixture.detectChanges();
2864+
2865+
const subscription = instance.select.selectionChange.subscribe(spy);
2866+
2867+
fixture.debugElement.query(By.css('.mat-select-trigger')).nativeElement.click();
2868+
fixture.detectChanges();
2869+
flush();
2870+
2871+
(overlayContainerElement.querySelector('mat-option') as HTMLElement).click();
2872+
fixture.detectChanges();
2873+
flush();
2874+
2875+
expect(spy).toHaveBeenCalledTimes(1);
2876+
2877+
subscription.unsubscribe();
2878+
}));
2879+
2880+
it('should not emit the change event multiple times when a reset option is ' +
2881+
'selected twice in a row', fakeAsync(() => {
2882+
const fixture = TestBed.createComponent(BasicSelectWithoutForms);
2883+
const instance = fixture.componentInstance;
2884+
const spy = jasmine.createSpy('change spy');
2885+
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).not.toHaveBeenCalled();
2900+
2901+
fixture.debugElement.query(By.css('.mat-select-trigger')).nativeElement.click();
2902+
fixture.detectChanges();
2903+
flush();
2904+
2905+
(overlayContainerElement.querySelector('mat-option') as HTMLElement).click();
2906+
fixture.detectChanges();
2907+
flush();
2908+
2909+
expect(spy).not.toHaveBeenCalled();
2910+
2911+
subscription.unsubscribe();
2912+
}));
2913+
28562914
});
28572915

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

src/lib/select/select.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -917,7 +917,10 @@ export class MatSelect extends _MatSelectMixinBase implements AfterContentInit,
917917
if (option.value == null && !this._multiple) {
918918
option.deselect();
919919
this._selectionModel.clear();
920-
this._propagateChanges(option.value);
920+
921+
if (this.value != null) {
922+
this._propagateChanges(option.value);
923+
}
921924
} else {
922925
option.selected ? this._selectionModel.select(option) : this._selectionModel.deselect(option);
923926

0 commit comments

Comments
 (0)