Reputation: 1064
I'm having an issue where I'm attempting to get the value of an error and display a custom error message via a html element. I'm using a Replay Subject to store the error and manage the state of the error in my Interceptor. I'm importing the interceptor correctly into the component and providing it in my module correctly. I'm confused as to why my error doesn't show up when getting an error response from my API.
Here's what I have so far
errorHandlerInterceptor.service.ts
export class ErrorHandlerInterceptor implements HttpInterceptor {
error: ReplaySubject<string> = new ReplaySubject<string>(1);
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return next.handle(request)
.pipe(
retry(1),
catchError((error: HttpErrorResponse) => {
let errorMessage = '';
if (error.error instanceof ErrorEvent) {
// client-side error
errorMessage = `Error: ${error.error.message}`;
} else {
// server-side error
errorMessage = `Error Code: ${error.status}`;
}
//window.alert(errorMessage);
this.error.next(errorMessage);
return throwError(this.error);
})
)
}
}
Then in the html, I async pipe the Replay Subject to only show the error message if the Replay Subject has a value.
component.html
<div
*ngIf="errorHandlerInterceptor.error | async"
class="app-alert--error"
>
<p class="app-alert__title">
ERROR
</p>
<p id="error-message">
{{ errorHandlerInterceptor.error | async }}
</p>
</div>
Any help or suggestions are greatly appreciated!
Upvotes: 0
Views: 537
Reputation: 11979
Importing the interceptor inside a component does not look like a good pattern to me.
A way to solve this might be to use a service that will propagate the error to its consumers. This way, from my perspective, we can achieve a better separation of concerns.
@Injectable({
providedIn: 'root'
})
export class ErrorService {
private errorStore = new BehaviorSubject(null);
public error$ = this.errorStore.asObservable();
emitError (err) {
this.errorStore.next(err);
}
}
@Component{/* ... */}
export class FooComponent {
get currentError$ () {
return this.errorService.error$;
}
constructor (private errorService: ErrorService) { }
}
<!-- ... -->
<div *ngIf="currentError$ | async">
Error!
</div>
<!-- ... -->
constructor (private errorService: ErrorService) { }
intercept (/* ... */) {
return next.handle(req)
.pipe(
/* ... */
catchError(err => {
/* ... */
// If error found
this.errorService.emitError(errorMessage);
/* ... */
}),
)
}
Upvotes: 1