【问题标题】:Open angular material Snackbar in service开角材料 Snackbar 在服务中
【发布时间】:2019-02-02 15:07:51
【问题描述】:

我想通过 Snackbar 向用户显示错误。当我通过组件打开 Snackbar 时,这完全没问题:

export class AppComponent implements OnInit {

    constructor(private snackBar: MatSnackBar) {
    }

    ngOnInit() {
        this.snackBar.open('message');
    }
}

但是当我想在我的 DataService 中打开一个 Snackbar 时,它会抛出这个错误:

ERROR TypeError: Cannot read property 'open' of undefined

我的数据服务如下所示:

export class DataService {

  private api = 'https://localhost:5001/api/';

  httpOptions = {
    headers: new HttpHeaders({
      'Content-Type': 'application/json'
    })
  };

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

  getData() {
    return this.http.get(this.api, this.httpOptions)
      .pipe(
        retry(3), // retry a failed request up to 3 times
        catchError(this.handleError) // then handle the error
      );
  }

  private handleError(error: HttpErrorResponse) {
    if (error.error instanceof ErrorEvent) {
      // A client-side or network error occurred.
      console.error('An error occurred:', error.error.message);
    } else {
      // The backend returned an unsuccessful response code.
      // The response body may contain clues as to what went wrong,
      console.error(
        `Backend returned code ${error.status}, ` +
        `body was: ${error.error}`);
    }

    this.snackBar.open('Something bad happened, please try again later.');

    // return an observable with a user-facing error message
    return throwError(
      'Something bad happened; please try again later.');
  }
}

因此,在第三次尝试获取数据后,它会进入 handleError() 并打开一个 SnackBar,并显示“发生了一些错误,请稍后再试。”

【问题讨论】:

  • 您能解释一下为什么您要在组件中的 ngOnInit 函数中打开吗?
  • 这只是一个展示在组件中可以打开 Snackbar 的示例。
  • 您好 tidi00,欢迎来到 StackOverflow!您能否检查您是否已将MatSnackBar 导入该文件并将MatSnackBarModule 导入您的主应用程序模块?
  • 您好 Edric,是的,我已将 MatSnackBar 导入 data.service.ts 并将 MatSnackBarModule 导入 app.module.ts。
  • 您是否在应用的模块文件中导入了服务?

标签: angular typescript angular-material


【解决方案1】:

这是因为catchError 中的当前作用域不是类本身,因此

this.snackbar

未定义。要解决这个问题,有两种方法

方法一:

您可以从另一个函数内部返回您的回调函数以将范围保留为

private handleError() {
    return (error: HttpErrorResponse) => {
        //your logic
    }
}

并将您的 catchError 方法更改为

catchError(this.handleError())  //note the parenthesis on handleError

方法二:

只需将catchError中的回调方法绑定到this

this.ErrorHandler.bind(this)

【讨论】:

    猜你喜欢
    • 2017-07-08
    • 1970-01-01
    • 1970-01-01
    • 2018-12-26
    • 2015-10-09
    • 1970-01-01
    • 2020-09-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多