Как сделать HTTP-запрос, когда пользователь вводит что-то в Angular и обрабатывает ошибку? - PullRequest
0 голосов
/ 10 июля 2020

Я читаю doc https://angular.io/guide/http#optimizing -server-interface-with-debouncing , чтобы научиться отправлять HTTP-запрос, когда пользователь что-то вводит.

Я могу заставить код работать (адаптировано из примера в do c), когда сервер REST API запущен и ответ - ОК. Но если в ответе HTTP есть какая-то ошибка (например, сервер не работает, код возврата не 2xx), мой код не будет работать. Т.е. если я введу что-то в поисковый запрос, он попытается отправить 1 HTTP-запрос и получит сообщение об ошибке, тогда больше HTTP-запрос не будет отправляться.

Мой фрагмент кода выглядит следующим образом (только основной код) :

Шаблон компонента

<form>
<input (keyup)="searchRecord($event.target.value)">
</form>

Search Item detail: <p>{{ record$ | async)?.detail }}</p>

Класс компонента

record$: Observable<any>;

ngOnInit(): void {
  this.record$ = this.searchText$.pipe(
    debounceTime(500),
    distintUntilChanged(),
    switchMap((recordId) => this.searchService.searchRecord(recordId))
  );
}

searchRecord(searchText: string) {
  this.searchText$.next(searchText);
}

Служба поиска

searchRecord(recordId: string) {
  return this.http.get<{detail: string}>(this.url + '/' + recordId);
}

1 Ответ

0 голосов
/ 10 июля 2020

Вы должны перехватить ошибку и обработать объект ошибки.

В вашем случае вы можете использовать * ngIf else, чтобы справиться со своим err sceanrio и показать другой шаблон при ошибке.

Шаблон компонента


       <form>
          <input (keyup)="searchRecord($event.target.value)">
       </form>
          
        <div class="search-result-container" *ngIf=" record$ | async as records; else loadingOrError">
          
             <div *ngIf="records.length > 0" class="row align-items-center header">
                <h2 class="col-12"><span class="count">{{ records.length }} Results</span> </h2>
             </div>
          
             <ul class="search-result">
                <li *ngFor="let record of records">
                  <a (click)="onSelect(record)"><span class="record.detail">{{record.detail| titlecase}}</span></a>
                </li>
             </ul>
        </div>
          
           <ng-template #loadingOrError>
          
              <ng-container *ngIf="errorObject; else loading">
          
                <span class="error">We are having issue, plesase try again.</span>
                    <!-- {{ errorObject }}  -->
              </ng-container>
           </ng-template> 

 

Класс компонента: используйте здесь CatchError. Подробнее о CatchError здесь.

  

        record$: Observable<any>;
        searchResult$: Observable<record[]>;
        searchTerm: Subject<string> = new Subject<string>();
        errorObject = null;
        
        ngOnInit(): void {
          this.searchResult$ = this.searchService.search(this.searchTerm).pipe(
              catchError(err => this.errorObject = err)
            );
        }
        
        
        searchRecord(term: string) {
            this.errorObject = null;
            this.searchTerm.next(term);
        }

      onSelect(record: any) {
      //Deal with the logic when a record is selected.
      }

Служба компонентов: ваш лог c перенесен в службу, чтобы код компонентов оставался кратким и понятным.


     search(searchTerm: Observable<string>): any {
        return searchTerm.pipe(
              debounceTime(500),
              distinctUntilChanged(),
              switchMap(term =>
                this.http.get<{detail: string}>(this.url + '/' + term );
              );
        }

...