我有一個進行預先輸入搜索的下拉文本框。當我搜索有效的專案名稱(存在于資料庫中)時,搜索作業正常并在下拉串列中回傳專案串列,以便在我鍵入時從中進行選擇。但是當我搜索無效文本時,API 回傳一個 400 錯誤(這很好),然后HttpErrorInterceptor在catchError()方法中攔截該回應,并拋出一個錯誤彈出視窗。我不希望彈出錯誤,我希望它將錯誤轉發到文本框邏輯,這樣我就可以在下拉串列中顯示“未找到專案”。
文本框 html(使用 Angular 的 NgbTypeahead):
<input
id="searchText"
type="text"
[(ngModel)]="selectedItem"
(selectItem)="onSelectItem($event)"
formControlName="searchText"
[ngbTypeahead]="search"
#instance="ngbTypeahead" />
文本框邏輯:
search = (input: Observable<string>) => {
return input.pipe(
debounceTime(500),
distinctUntilChanged(),
switchMap((text) => text.length < 2 ? this.clearItems() //clearItems() is irrelavant
: this.itemService.getItemSearchData(text).pipe(
map(responseObj => {
const itemList = responseObj.data ? orderBy(responseObj.data, ['itemName'], ['asc']) : [];
if (itemList.length === 0) {
// this is what I want it to do when I get the error response
itemList.push({ itemName: 'No Items Found' } as ItemList);
}
return itemList;
})
)));
}
// This is in the ItemService class.
getItemSearchData(searchTerm: string): Observable<any> {
const searchItem = {
"filterBy": {
"key": "itemname",
"value": searchTerm
}
}
return this.http.post(this.itemApiUrl, searchItem, { headers: this.headers });
}
這是攔截器:
@Injectable()
export class HttpErrorInterceptor implements HttpInterceptor {
constructor(private matDialog: MatDialog) { }
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return next.handle(request)
.pipe(
catchError((error: HttpErrorResponse) => {
let errorMessage = 'Unknown error!';
if (error.error instanceof ErrorEvent) {
errorMessage = `Error: ${error.error.message}`;
} else {
errorMessage = `Error Code: ${error.status}\nMessage: ${error.message}`;
}
// the error popup. I DON'T want to throw this when I get the 404 response.
this.matDialog.open(PopupComponent, {
data: { actionDesctiption: errorMessage, isError: true },
panelClass: 'custom-dialog-container'
});
return throwError(error);
})
);
}
我試過這個:Angular: intercept HTTP errors and continue chain,但頂級解決方案的return of(new HttpResponse...;宣告給了我錯誤Type 'Observable<unknown>' is not assignable to type 'Observable<HttpEvent<any>>'。我也嘗試過回傳next.handle(request)和new Observable<HttpEvent<any>>()。
當我在該map(responseObj => 行放置一個斷點時,它總是說“未定義responseObj”。
當 API 回傳 400 錯誤時,如何讓下拉選單顯示“未找到專案”?
uj5u.com熱心網友回復:
目前尚不清楚從您的 API 回傳的資料的結構是什么。假設 API 以這種格式回傳資料:({ itemName: string }[]即{ itemName: string }物件陣列,您可以使用 http 攔截器檢查 404 錯誤,然后像這樣更改回應:
import { HttpRequest, HttpResponse, HttpHandler, HttpEvent, HttpInterceptor } from '@angular/common/http';
import { HttpErrorResponse } from '@angular/common/http';
import { of, throwError } from 'rxjs';
@Injectable()
export class HttpErrorInterceptor implements HttpInterceptor {
constructor(private matDialog: MatDialog) { }
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return next.handle(request)
.pipe(
catchError((error) => {
let errorMessage = 'Unknown error!';
if (error.error instanceof ErrorEvent) {
errorMessage = `Error: ${error.error.message}`;
} else {
errorMessage = `Error Code: ${error.status}\nMessage: ${error.message}`;
}
// check for a 404 error response
if (error instanceof HttpErrorResponse && error.status === 404) {
return this.returnCustomData([{ itemName: 'No Items Found' }]); // returns a response, and doesn't throw the error
}
// the error popup. I DON'T want to throw this when I get the 404 response.
this.matDialog.open(PopupComponent, {
data: { actionDesctiption: errorMessage, isError: true },
panelClass: 'custom-dialog-container'
});
return throwError(error);
})
);
}
private returnCustomData(body) {
return of(new HttpResponse({ status: 200, body }));
}
}
注意:同樣,我假設您的 API 回傳一個{ itemName: string }物件陣列,這就是為什么我在呼叫時在陣列中使用一個物件returnCustomData。請記住更改發送到的資料物件returnCustomData以匹配您的 API 回傳的實際資料格式,就好像它只回傳一個結果,包含“未找到專案”字樣。
uj5u.com熱心網友回復:
我知道你的攔截器在處理任何請求的所有 HTTP 錯誤,但是,因為你需要在你的組件中出現那個訊息錯誤,你是否也在你的服務管道中添加一個 catchError 呢?
search = (input: Observable<string>) => {
return input.pipe(
debounceTime(500),
distinctUntilChanged(),
switchMap((text) => text.length < 2 ? this.clearItems()
: this.itemService.getItemSearchData(text)
.pipe(
map(responseObj => {
const itemList = responseObj.data ? orderBy(responseObj.data, ['itemName'], ['asc']) : [];
return itemList;
}),
catchError(() => {
itemList.push({ itemName: 'No Items Found' } as ItemList));
of('');
}
)));
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/408387.html
標籤:
上一篇:'Observable'不可分配給型別'EffectResult'
下一篇:Angular-重繪內容的問題
