From 1636e9f5188debc256b17c4a7fa93884f9f2e823 Mon Sep 17 00:00:00 2001 From: Thomas Heller Date: Thu, 23 Jul 2020 17:03:41 +0200 Subject: [PATCH] fix(quick-filter): Fixes an issue where an ECAC error was thrown. Fixes an expression changed after checked error that was thrown in the filter field. Thank you @areknow for pointing that out and helping us investigate. Fixes #1305 --- .../quick-filter/src/quick-filter.spec.ts | 14 +++++++++----- .../experimental/quick-filter/src/quick-filter.ts | 15 ++++++++++++--- 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/libs/barista-components/experimental/quick-filter/src/quick-filter.spec.ts b/libs/barista-components/experimental/quick-filter/src/quick-filter.spec.ts index af516d54f5..9df20a47f1 100644 --- a/libs/barista-components/experimental/quick-filter/src/quick-filter.spec.ts +++ b/libs/barista-components/experimental/quick-filter/src/quick-filter.spec.ts @@ -101,7 +101,7 @@ describe('dt-quick-filter', () => { ); }); - it('should set the filters on the filter field if they are set on the quick-filter', () => { + it('should set the filters on the filter field if they are set on the quick-filter', fakeAsync(() => { expect(quickFilterInstance.filters).toHaveLength(0); const filters = [ [ @@ -111,9 +111,10 @@ describe('dt-quick-filter', () => { ]; quickFilterInstance.filters = filters; - fixture.detectChanges(); + zone.simulateZoneExit(); + expect(filterFieldInstance.filters).toMatchObject(filters); - }); + })); it('should reset the filters if the data source gets switched', () => { quickFilterInstance.filters = [ @@ -156,13 +157,16 @@ describe('dt-quick-filter', () => { expect(groups).toMatchObject(['AUT', 'USA']); }); - it('should dispatch an event with the changes on selecting an option', () => { + it('should dispatch an event with the changes on selecting an option', fakeAsync(() => { const changeSpy = jest.spyOn(fixture.componentInstance, 'filterChanges'); expect(changeSpy).toHaveBeenCalledTimes(0); const checkboxes = fixture.debugElement .queryAll(By.directive(DtCheckbox)) .map((el) => el.query(By.css('label'))); + // Zone must be stable at least once before the quickfilter can be interacted with. + zone.simulateZoneExit(); + dispatchMouseEvent(checkboxes[1].nativeElement, 'click'); fixture.detectChanges(); @@ -174,7 +178,7 @@ describe('dt-quick-filter', () => { ], ]); changeSpy.mockClear(); - }); + })); it('should propagate currentFilterChanges event when emitted on the filter field', fakeAsync(() => { const spy = jest.fn(); diff --git a/libs/barista-components/experimental/quick-filter/src/quick-filter.ts b/libs/barista-components/experimental/quick-filter/src/quick-filter.ts index b9723d702f..94d943c9e9 100644 --- a/libs/barista-components/experimental/quick-filter/src/quick-filter.ts +++ b/libs/barista-components/experimental/quick-filter/src/quick-filter.ts @@ -168,9 +168,18 @@ export class DtQuickFilter implements AfterViewInit, OnDestroy { /** Angular life-cycle hook that will be called after the view is initialized */ ngAfterViewInit(): void { - // When the filters changes apply them to the filter field - this._activeFilters$ - .pipe(takeUntil(this._destroy$)) + // We need to wait for the first on stable call, otherwise the + // underlying filterfield will thow an expression changed after checked + // error. Deferring the first filter setting. + // Relates to a very weird and hard to reproduce bug described in + // https://github.com/dynatrace-oss/barista/issues/1305 + this._zone.onStable + .pipe( + take(1), + switchMap(() => this._activeFilters$), + takeUntil(this._destroy$), + ) + // When the filters changes apply them to the filter field .subscribe((filters) => { if (this._filterField.filters !== filters) { this._filterField.filters = filters;