From 87bbfc52c859b4d35aa571bf8400f85f1e6876c6 Mon Sep 17 00:00:00 2001 From: Kristiyan Kostadinov Date: Tue, 13 Feb 2018 16:39:41 +0100 Subject: [PATCH] fix(input): AutofillMonitor stream not being completed when stopping monitoring (#9886) Currently we only remove the event listeners and CSS classes when we stop monitoring an element, however any subscriptions are still live. These changes complete the subject since it won't be reused if we decide to start monitoring again. --- src/lib/input/autofill.spec.ts | 13 +++++++++++++ src/lib/input/autofill.ts | 14 +++++++------- 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/src/lib/input/autofill.spec.ts b/src/lib/input/autofill.spec.ts index f175ff4efa7..8a5dbea6069 100644 --- a/src/lib/input/autofill.spec.ts +++ b/src/lib/input/autofill.spec.ts @@ -137,6 +137,19 @@ describe('AutofillMonitor', () => { autofillMonitor.stopMonitoring(inputEl); expect(inputEl.classlist).not.toContain('mat-input-autofilled'); }); + + it('should complete the stream when monitoring is stopped', () => { + const element = testComponent.input1.nativeElement; + const autofillStream = autofillMonitor.monitor(element); + const spy = jasmine.createSpy('autofillStream complete'); + + autofillStream.subscribe(undefined, undefined, spy); + expect(spy).not.toHaveBeenCalled(); + + autofillMonitor.stopMonitoring(element); + expect(spy).toHaveBeenCalled(); + }); + }); describe('matAutofill', () => { diff --git a/src/lib/input/autofill.ts b/src/lib/input/autofill.ts index 098d3b368f4..163c9ff4c18 100644 --- a/src/lib/input/autofill.ts +++ b/src/lib/input/autofill.ts @@ -97,8 +97,10 @@ export class AutofillMonitor implements OnDestroy { */ stopMonitoring(element: Element) { const info = this._monitoredElements.get(element); + if (info) { info.unlisten(); + info.subject.complete(); element.classList.remove('mat-input-autofill-monitored'); element.classList.remove('mat-input-autofilled'); this._monitoredElements.delete(element); @@ -106,10 +108,7 @@ export class AutofillMonitor implements OnDestroy { } ngOnDestroy() { - this._monitoredElements.forEach(info => { - info.unlisten(); - info.subject.complete(); - }); + this._monitoredElements.forEach((_info, element) => this.stopMonitoring(element)); } } @@ -119,13 +118,14 @@ export class AutofillMonitor implements OnDestroy { selector: '[matAutofill]', }) export class MatAutofill implements OnDestroy, OnInit { - @Output() matAutofill = new EventEmitter(); + @Output() matAutofill: EventEmitter = new EventEmitter(); constructor(private _elementRef: ElementRef, private _autofillMonitor: AutofillMonitor) {} ngOnInit() { - this._autofillMonitor.monitor(this._elementRef.nativeElement) - .subscribe(event => this.matAutofill.emit(event)); + this._autofillMonitor + .monitor(this._elementRef.nativeElement) + .subscribe(event => this.matAutofill.emit(event)); } ngOnDestroy() {