Skip to content

Commit 1218592

Browse files
crisbetojelbourn
authored andcommitted
fix(autocomplete): not emitting opened event if options come in after open (#15582)
Fixes `mat-autocomplete` not emitting its `opened` event if it is opened without any options and then the options come in at a later point. Fixes #15573.
1 parent e488152 commit 1218592

File tree

2 files changed

+45
-18
lines changed

2 files changed

+45
-18
lines changed

src/material/autocomplete/autocomplete-trigger.ts

Lines changed: 26 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -506,24 +506,32 @@ export class MatAutocompleteTrigger implements ControlValueAccessor, OnChanges,
506506

507507
// When the zone is stable initially, and when the option list changes...
508508
return merge(firstStable, optionChanges)
509-
.pipe(
510-
// create a new stream of panelClosingActions, replacing any previous streams
511-
// that were created, and flatten it so our stream only emits closing events...
512-
switchMap(() => {
513-
this._resetActiveItem();
514-
this.autocomplete._setVisibility();
515-
516-
if (this.panelOpen) {
517-
this._overlayRef!.updatePosition();
518-
}
519-
520-
return this.panelClosingActions;
521-
}),
522-
// when the first closing event occurs...
523-
take(1)
524-
)
525-
// set the value, close the panel, and complete.
526-
.subscribe(event => this._setValueAndClose(event));
509+
.pipe(
510+
// create a new stream of panelClosingActions, replacing any previous streams
511+
// that were created, and flatten it so our stream only emits closing events...
512+
switchMap(() => {
513+
const wasOpen = this.panelOpen;
514+
this._resetActiveItem();
515+
this.autocomplete._setVisibility();
516+
517+
if (this.panelOpen) {
518+
this._overlayRef!.updatePosition();
519+
520+
// If the `panelOpen` state changed, we need to make sure to emit the `opened`
521+
// event, because we may not have emitted it when the panel was attached. This
522+
// can happen if the users opens the panel and there are no options, but the
523+
// options come in slightly later or as a result of the value changing.
524+
if (wasOpen !== this.panelOpen) {
525+
this.autocomplete.opened.emit();
526+
}
527+
}
528+
529+
return this.panelClosingActions;
530+
}),
531+
// when the first closing event occurs...
532+
take(1))
533+
// set the value, close the panel, and complete.
534+
.subscribe(event => this._setValueAndClose(event));
527535
}
528536

529537
/** Destroys the autocomplete suggestion panel. */

src/material/autocomplete/autocomplete.spec.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -421,6 +421,25 @@ describe('MatAutocomplete', () => {
421421
expect(fixture.componentInstance.openedSpy).not.toHaveBeenCalled();
422422
});
423423

424+
it('should emit the `opened` event if the options come in after the panel is shown',
425+
fakeAsync(() => {
426+
fixture.componentInstance.filteredStates = fixture.componentInstance.states = [];
427+
fixture.detectChanges();
428+
429+
fixture.componentInstance.trigger.openPanel();
430+
fixture.detectChanges();
431+
432+
expect(fixture.componentInstance.openedSpy).not.toHaveBeenCalled();
433+
434+
fixture.componentInstance.filteredStates = fixture.componentInstance.states =
435+
[{name: 'California', code: 'CA'}];
436+
fixture.detectChanges();
437+
tick();
438+
fixture.detectChanges();
439+
440+
expect(fixture.componentInstance.openedSpy).toHaveBeenCalled();
441+
}));
442+
424443
it('should not emit the opened event multiple times while typing', fakeAsync(() => {
425444
fixture.componentInstance.trigger.openPanel();
426445
fixture.detectChanges();

0 commit comments

Comments
 (0)