【问题标题】:Can I use a snackbar inside my service?我可以在我的服务中使用小吃店吗?
【发布时间】:2018-10-09 22:54:27
【问题描述】:

如果发生错误,我想从调用 api 的服务调用中获取错误详细信息。

例如如果返回的 http 错误是 422,我想显示一条用户友好的消息。

所以,这是我的服务类:

@Injectable()
export class TransactionService {

  private baseUrl = 'http://foo.bar/api';
  private body;
  private headers;
  private options;

  constructor(private http: HttpClient, private snackBar: MatSnackBar) {

  }

  openSnackBar(message: string) {
    this.snackBar.open(message, null, {duration: 5000});
  }

  errorHandler(error: HttpErrorResponse) {

    console.log(error.status);
    if (error.status === 422) {
      this.openSnackBar('Number already exists');
    } else {
    return Observable.throw(error.message || 'Server Error');
    }
  }

  SubmitTransaction(transactionRequest: ITransactionRequestObj): Observable<TransactionResponse> {
    this.body =  JSON.stringify(transactionRequest);
    this.headers = new HttpHeaders().set('Content-Type', 'application/json');
    this.headers.append('Accept', 'application/json');
    this.options = new RequestOptions({headers: this.headers});
    console.log(JSON.stringify(transactionRequest));
    return this.http.post<TransactionResponse>(this.baseUrl + '/transactions/new',  this.body, this.options)
                .catch(this.errorHandler);
  }

}

我做了一个 console.log,当出现 422 错误时,我确实得到了正确的错误状态编号。但是,小吃栏不会弹出,因为我收到了这个错误:

core.js:1448 ERROR TypeError: this.openSnackBar is not a function
    at CatchSubscriber.TransactionService.errorHandler [as selector] (transaction.service.ts:49)
    at CatchSubscriber.error (catchError.js:105)
    at MapSubscriber.Subscriber._error (Subscriber.js:131)
    at MapSubscriber.Subscriber.error (Subscriber.js:105)
    at FilterSubscriber.Subscriber._error (Subscriber.js:131)
    at FilterSubscriber.Subscriber.error (Subscriber.js:105)
    at MergeMapSubscriber.OuterSubscriber.notifyError (OuterSubscriber.js:24)
    at InnerSubscriber._error (InnerSubscriber.js:28)
    at InnerSubscriber.Subscriber.error (Subscriber.js:105)
    at XMLHttpRequest.onLoad (http.js:2283)

是因为我不应该/不能在我的服务中使用snackbar(只有组件?)?

相同的小吃店代码在我的组件中运行良好,但我无法在我的组件中获取错误状态。

这也是我的组件类中的服务调用:

this._transactionService.SubmitTransaction(this.transactionObj).subscribe(data => {
        if (data._errorDetails._status === '201') {
          //do some action 
        }
      }, (err) => {
        console.log(err);
        if (err.status === 422) { //also tried this inside my component err.status is undefined. However err is the server error message.
        //do some action 
        }
      });

【问题讨论】:

    标签: angular typescript angular-material


    【解决方案1】:

    我假设您需要绑定正确的 this 上下文才能使其正常工作:

    .catch(this.errorHandler.bind(this));
    

    或者您也可以使用以下选项:

    .catch((e) => this.errorHandler(e));
    

    或局部粗箭头函数:

    errorHandler = (error: HttpErrorResponse) => {
      ...
    }
    

    更多详情见:

    【讨论】:

    • 我认为你是对的。你建议的方法对我不起作用。第一个导致我的 observable 错误,第二个在编译时给我这个错误:“core.js:1448 ERROR TypeError: You provide 'undefined' where a stream is expected. You can provide an Observable,承诺、数组或可迭代”。我还没有尝试过第三种选择。但我记得我之前也遇到过类似的问题,并且能够通过 self 解决。让我试试
    • 你必须从 errorHandler 方法返回 Observable。 if (error.status === 422) { this.openSnackBar('Number already exists'); return Observable.throw('something) 但你只在其他情况下返回 observable
    • 你能不能也看看这个问题:stackoverflow.com/questions/50091668/…如果你有时间?谢谢!
    猜你喜欢
    • 2020-08-23
    • 1970-01-01
    • 2019-02-15
    • 2018-02-20
    • 2020-10-13
    • 2020-06-30
    • 2010-09-07
    • 2020-07-25
    相关资源
    最近更新 更多