Reputation:
I listen typing text from input field:
Observable.fromEvent(this.inputSearch.nativeElement, "keyup"). .subscribe((query => {
this.executeSearchTips(query);
});
private executeSearchTips(query: string): void {
from(this.searchRequest(query, true, SearchType.WildcardEveryWord))
.pipe(filter((response: any) => response || !response.result))
.subscribe((response) => {
this.showSearchResultContent.next(true); // Here is issue
});
}
Also there is another method that reacts by click:
public searchByEnter(e) {
if (e.keyCode === 13)
this.showSearchResultContent.next(false); // Here is issue
// Http request below and logic
}
My issue is that if user is typing text and gets result then I set this to true: this.showSearchResultContent.next(true);
But if user started typing text and instantly pressed enter, then executeSearchTips
should be canceled and this.showSearchResultContent
should be false.
Now I get first result from searchByEnter()
then from executeSearchTips()
and executeSearchTips()
opens this.showSearchResultContent.next(true);
. But should not!
How to cancel executeSearchTips
if enter was pressed?
Anyway I can not cancel HTTP request executeSearchTips
.
Upvotes: 0
Views: 71
Reputation: 396
There is an anti-pattern in your code. You should avoid subscribes inside subscribes (Observable.fromEvent(this.inputSearch.nativeElement, "keyup").subscribe triggers executeSearchTips with another subscribe)
It's hard to understand what you are trying to achieve with handling Enter as a special case, so I am not sure about a lot of things, but I gave it a try.
showSearchResultContent = new Subject<boolean>();
@ViewChild("search") input: ElementRef;
private searchRequest(searchText: string): Observable<any> {
// just a fake as an example
const responseFromServer = { result: { name: "Justine"} };
return of(responseFromServer)
}
ngAfterViewInit(): void {
const $search = fromEvent(this.input.nativeElement, "keyup");
$search
.pipe(
switchMap((event: KeyboardEvent) => {
const showResultContent = event.keyCode === 13;
// not sure what "showSearchResultContent.next" does, either trigger it here or later in the subscribe.
// you could start different requests based on the keyCode here if needed.
return combineLatest([
of(showResultContent),
this.searchRequest((<HTMLInputElement>event.target).value).pipe(filter((response: any) => response || !response.result))
])
})
)
.subscribe({
next: ([showResultContent, response]) => {
this.showSearchResultContent.next(showResultContent);
// more logic
console.log("subscribe: ", showResultContent, response);
}
});
}
Upvotes: 1