Skip to content

Commit e34cffd

Browse files
committed
fix(material/timepicker): ensure selected event fires after form control value is updated
1 parent d02338b commit e34cffd

File tree

2 files changed

+37
-1
lines changed

2 files changed

+37
-1
lines changed

src/material/timepicker/timepicker.spec.ts

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,39 @@ describe('MatTimepicker', () => {
135135
}),
136136
);
137137
}));
138+
139+
it('should emit selected event after form control value is updated', fakeAsync(() => {
140+
const fixture = TestBed.createComponent(TimepickerWithForms);
141+
const control = fixture.componentInstance.control;
142+
fixture.detectChanges();
143+
144+
let formControlValue: Date | null = null;
145+
let eventValue: Date | null = null;
146+
147+
// Subscribe to form control changes
148+
control.valueChanges.subscribe(value => {
149+
formControlValue = value;
150+
});
151+
152+
// Subscribe to selected event
153+
fixture.componentInstance.input.timepicker().selected.subscribe(event => {
154+
eventValue = event.value;
155+
// At this point, form control should already be updated
156+
expect(control.value).toBeTruthy();
157+
expectSameTime(control.value, event.value);
158+
});
159+
160+
getInput(fixture).click();
161+
fixture.detectChanges();
162+
getOptions()[3].click(); // Select 1:30 AM
163+
fixture.detectChanges();
164+
flush();
165+
166+
expect(formControlValue).toBeTruthy();
167+
expect(eventValue).toBeTruthy();
168+
expectSameTime(formControlValue, eventValue);
169+
expectSameTime(control.value, createTime(1, 30));
170+
}));
138171
});
139172

140173
describe('input behavior', () => {

src/material/timepicker/timepicker.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -296,7 +296,10 @@ export class MatTimepicker<D> implements OnDestroy, MatOptionParentComponent {
296296
current.deselect(false);
297297
}
298298
});
299-
this.selected.emit({value: option.value, source: this});
299+
// Emit the selected event after a microtask to ensure the form control is updated first
300+
Promise.resolve().then(() => {
301+
this.selected.emit({value: option.value, source: this});
302+
});
300303
this._input()?.focus();
301304
}
302305

0 commit comments

Comments
 (0)