I have a dropdown text box that does type-ahead search. When I search for a valid item name (that exists in the DB), the search works fine and returns a list of items in the drop down to select from as I type. But when I search for invalid text, the API returns a 400 error (this is good), then the HttpErrorInterceptor intercepts that response in the catchError() method, and throws up an error popup. I don't want the error popup, I want it to forward the error to the text box logic so I can just display 'No Items Found' in the dropdown.
Text box html (uses Angular's NgbTypeahead):
<input
id="searchText"
type="text"
[(ngModel)]="selectedItem"
(selectItem)="onSelectItem($event)"
formControlName="searchText"
[ngbTypeahead]="search"
#instance="ngbTypeahead" />
Text box logic:
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 });
}
This is the interceptor:
@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);
})
);
}
I have tried this: Angular: intercept HTTP errors and continue chain, but the top solutions's return of(new HttpResponse...; statement gave me the error Type 'Observable<unknown>' is not assignable to type 'Observable<HttpEvent<any>>'. I also tried returning next.handle(request) and new Observable<HttpEvent<any>>().
When I place a breakpoint at the map(responseObj => line, it always says "responseObj is not defined".
How can I get the dropdown to show 'No Items Found' when the API returns the 400 error?