iT邦幫忙

0

Rxjs Observable error to angular error handler(內含3個Angular問題)

Leo 2020-04-14 01:07:07471 瀏覽

問題1: 有沒有辦法將Observable內的error throw到Angular ErrorHandler

目前試了很多種方法,在pipe裡throw error或在訂閱資料subscribe裡將資料throw出去

this._adapter.singleAdapter(
    () => { return self._auth.signUp(1, '1', '1'); }
).subscribe((data) => {
    throw new Error(data.message);
});

但最後的error都會被zone.js吃掉,是因為Observable的error作用域有特別的處理嗎?

Google了一下,發現了這個issue,好像是zone.js的問題(?
但作者已將zone.js改版(0.8.17),我的版本為0.10.2,但還是有這個狀況

問題2: 如何建立一支真正的Singleton Service

該如何建立一支整個Application都是同一個instance的service
在service裡provide給root

@Injectable({
  providedIn: 'root'
})

並在app.module.ts,添加進providers,這個方法似乎並不能保證整個Application都是同一個instance的service

官方文件的forRoot寫法還是看不太懂

問題3: 大家會怎麼切換顯示頁面在非同步處理時的Loading特效

我現在是建立一支service,裡面有一個變數BehaviorSubject<boolean>
紀錄這個Loading特效是否打開用的,並在app.component.ts subscribe這個變數

我有另一個想法是用AjaxInterceptor去控制,當request產生的時候打開特效,response回來的時候關閉特效,我用一般HTTPClient method那些都可以成功觸發AjaxInterceptor
但專案用firebase cloud functions部署API,在前端用AngularFireFunctions拿到API後,呼叫API卻不能觸發AngularFireFunctions,很疑惑為什麼會有這個情況,因為AngularFireFunctions也是走HTTP Method

let api = this._fireFunctions.httpsCallable('apiName');
await api();

而且如果這個方法成功的話,如果一個method裡用async/await很多非同步方法,頁面是不是會一閃一閃的?

想請問有沒有其他通俗的方法或比較正確的方法在處理這件事情

1 個回答

0
tso1158687
iT邦新手 5 級 ‧ 2020-04-14 14:13:37
最佳解答

問題一:
這個問題有點看不太懂,不過一般來說,取得rxjs的錯誤方法為

someObservable.pipe(
  // 使用 catchError operator
  catchError(error => {
    console.log(error);
    throwError(error);
  })
).subscribe(
  result => {},
  error => { /* 處理錯誤 */ }
);

問題二:
如果你使用cli建立出來的service,基本上就是單一實例,可以保證所有的頁面取到的service都是同一個。至於你說的forRoot是給一個模組,被其他不同的模組同時引用的時候使用的,不需要用在service上面

問題三:
你用一個service去建立behaviorSubject的想法我認為是行得通的
但是如果你要去攔截angular裡面所有非同步的方法,不需要使用到AjaxInterceptor,可以使用angular內建原生地interceptor,相容性保證最好,可以攔截到所有的非同步行為

Leo iT邦新手 5 級 ‧ 2020-04-14 23:28:42 檢舉

問題1:

這是我ts的程式碼

self._adapter.singleAdapter(
      () => { return self._auth.signUp(Number(self.session), self.group, self.englishName); }
    ).subscribe((data) => {
      throw new Error(data.message);
    });

我有一個ErrorHandler

export class ErrorHandlerService implements ErrorHandler {

  constructor() { }

  handleError(error) {

    const self = this;

    alert(error.message.toString());

  }

}

結果最後執行結果資料並沒有被alert出來,而是產生了Uncaught Error在Consoleg視窗裡,我有試過在一般的程式碼裡throw error,是可以進到Error Handler裡面的

問題3:

我想問你的原生的Interceptor指的是HttpInterceptor嗎?
我現在的是這樣

export class AjaxInterceptorService implements HttpInterceptor {

  constructor() { }

  intercept(
    req: HttpRequest<any>, next: HttpHandler
  ): Observable<HttpEvent<any>> {
    console.log(req);
    return next.handle(req);
  }
}

我要發表回答

立即登入回答