带rxjs重播主题的Http错误处理程序拦截器配置-Angular

时间:2019-12-11 17:02:38

标签: javascript angular typescript

我遇到一个问题,尝试获取错误值并通过html元素显示自定义错误消息。我正在使用重播主题来存储错误并在拦截器中管理错误的状态。我正在将拦截器正确导入组件中,并在我的模块中正确提供它。我很困惑为什么从我的API得到错误响应时为什么我的错误没有出现。

这是我到目前为止所拥有的

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);
        })
      )
  }
}

然后在html中,我异步管道重播主题以仅在重播主题具有值的情况下显示错误消息。

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>

任何帮助或建议,我们将不胜感激!

1 个答案:

答案 0 :(得分:1)

将拦截器导入组件内部对我来说似乎不是一个好模式。

解决此问题的一种方法可能是使用将错误传播给其消费者的服务。 从我的角度来看,这样可以更好地关注点分离

error.service.ts

@Injectable({
    providedIn: 'root'
})
export class ErrorService {
    private errorStore = new BehaviorSubject(null);
    public error$ = this.errorStore.asObservable();

    emitError (err) {
        this.errorStore.next(err);
    }
}

foo.component.ts

@Component{/* ... */}
export class FooComponent {

    get currentError$ () {
        return this.errorService.error$;
    }

    constructor (private errorService: ErrorService) { }
}

foo.component.html

<!-- ... -->

<div *ngIf="currentError$ | async">
    Error!
</div>

<!-- ... -->

error.interceptor.ts

constructor (private errorService: ErrorService) { }

intercept (/* ... */) {
    return next.handle(req)
        .pipe(
            /* ... */
            catchError(err => {
                /* ... */

                // If error found
                this.errorService.emitError(errorMessage);

                /* ... */
            }),
        )
}