user14516403
user14516403

Reputation:

How to solve async issue?

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

Answers (1)

sombrerogalaxy
sombrerogalaxy

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

Related Questions