Skip to content

Commit 16e2732

Browse files
authored
fix: adding debounce subscription on component init (#519)
* fix: adding debounce subscription on component init * refactor: add tests
1 parent 509c313 commit 16e2732

File tree

2 files changed

+80
-9
lines changed

2 files changed

+80
-9
lines changed
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
import { fakeAsync } from '@angular/core/testing';
2+
import { By } from '@angular/platform-browser';
3+
import { runFakeRxjs } from '@hypertrace/test-utils';
4+
import { createHostFactory, Spectator } from '@ngneat/spectator/jest';
5+
import { SearchBoxComponent } from './search-box.component';
6+
7+
describe('Search box Component', () => {
8+
let spectator: Spectator<SearchBoxComponent>;
9+
10+
const createHost = createHostFactory({
11+
component: SearchBoxComponent,
12+
shallow: true
13+
});
14+
15+
test('should work with default values', fakeAsync(() => {
16+
spectator = createHost(
17+
`<ht-search-box [placeholder]="placeholder" (valueChange)="onValueChange($event)"></ht-search-box>`,
18+
{
19+
hostProps: {
20+
placeholder: 'Test Placeholder'
21+
}
22+
}
23+
);
24+
25+
const inputDebugElement = spectator.debugElement.query(By.css('input'));
26+
expect((inputDebugElement.nativeElement as HTMLInputElement)?.placeholder).toEqual('Test Placeholder');
27+
spectator.component.value = 'Test';
28+
29+
runFakeRxjs(({ expectObservable }) => {
30+
expectObservable(spectator.component.valueChange).toBe('x', {
31+
x: 'Test'
32+
});
33+
34+
spectator.triggerEventHandler(inputDebugElement, 'input', spectator.component.value);
35+
spectator.tick();
36+
});
37+
}));
38+
39+
test('should work with arbitrary debounce time', fakeAsync(() => {
40+
spectator = createHost(
41+
`<ht-search-box [placeholder]="placeholder" [debounceTime]="debounceTime" (valueChange)="onValueChange($event)"></ht-search-box>`,
42+
{
43+
hostProps: {
44+
placeholder: 'Test Placeholder',
45+
debounceTime: 200
46+
}
47+
}
48+
);
49+
50+
const inputDebugElement = spectator.debugElement.query(By.css('input'));
51+
expect((inputDebugElement.nativeElement as HTMLInputElement)?.placeholder).toEqual('Test Placeholder');
52+
spectator.component.value = 'Test2';
53+
54+
runFakeRxjs(({ expectObservable }) => {
55+
expectObservable(spectator.component.valueChange).toBe('200ms x', {
56+
x: 'Test2'
57+
});
58+
59+
spectator.triggerEventHandler(inputDebugElement, 'input', spectator.component.value);
60+
spectator.tick();
61+
});
62+
}));
63+
});

projects/components/src/search-box/search-box.component.ts

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { ChangeDetectionStrategy, Component, EventEmitter, Input, OnChanges, Output } from '@angular/core';
1+
import { ChangeDetectionStrategy, Component, EventEmitter, Input, OnChanges, OnInit, Output } from '@angular/core';
22
import { IconType } from '@hypertrace/assets-library';
33
import { SubscriptionLifecycle, TypedSimpleChanges } from '@hypertrace/common';
44
import { Subject } from 'rxjs';
@@ -33,15 +33,15 @@ import { IconSize } from '../icon/icon-size';
3333
</div>
3434
`
3535
})
36-
export class SearchBoxComponent implements OnChanges {
36+
export class SearchBoxComponent implements OnInit, OnChanges {
3737
@Input()
3838
public placeholder: string = 'Search';
3939

4040
@Input()
4141
public value: string = '';
4242

4343
@Input()
44-
public debounceTime: number = 0;
44+
public debounceTime?: number;
4545

4646
@Output()
4747
public readonly valueChange: EventEmitter<string> = new EventEmitter();
@@ -55,14 +55,13 @@ export class SearchBoxComponent implements OnChanges {
5555
public isFocused: boolean = false;
5656
private readonly debouncedValueSubject: Subject<string> = new Subject();
5757

58+
public ngOnInit(): void {
59+
this.setDebouncedSubscription();
60+
}
61+
5862
public ngOnChanges(changes: TypedSimpleChanges<this>): void {
5963
if (changes.debounceTime) {
60-
this.subscriptionLifecycle.unsubscribe();
61-
this.subscriptionLifecycle.add(
62-
this.debouncedValueSubject
63-
.pipe(debounceTime(this.debounceTime))
64-
.subscribe(value => this.valueChange.emit(value))
65-
);
64+
this.setDebouncedSubscription();
6665
}
6766
}
6867

@@ -82,4 +81,13 @@ export class SearchBoxComponent implements OnChanges {
8281
this.value = '';
8382
this.onValueChange();
8483
}
84+
85+
private setDebouncedSubscription(): void {
86+
this.subscriptionLifecycle.unsubscribe();
87+
this.subscriptionLifecycle.add(
88+
this.debouncedValueSubject
89+
.pipe(debounceTime(this.debounceTime ?? 0))
90+
.subscribe(value => this.valueChange.emit(value))
91+
);
92+
}
8593
}

0 commit comments

Comments
 (0)