Programing

RxJS 맵 연산자 (각도)에서 오류를 발생시키는 방법

crosscheck 2020. 12. 12. 10:06
반응형

RxJS 맵 연산자 (각도)에서 오류를 발생시키는 방법


조건에 따라 Observable의 연산자 에서 오류를 던지고 싶습니다 . 예를 들어 올바른 API 데이터가 수신되지 않은 경우. 다음 코드를 참조하십시오.

private userAuthenticate( email: string, password: string ) {
    return this.httpPost(`${this.baseApiUrl}/auth?format=json&provider=login`, {userName: email, password: password})
        .map( res => { 
            if ( res.bearerToken ) {
                return this.saveJwt(res.bearerToken); 
            } else {
                // THIS DOESN'T THROW ERROR --------------------
                return Observable.throw('Valid token not returned');
            }
        })
        .catch( err => Observable.throw(this.logError(err) )
        .finally( () => console.log("Authentication done.") );
}

기본적으로 코드에서 볼 수 있듯이 응답 (res 객체)에 'bearerToken'이 없으면 오류를 버리고 싶습니다. 그래서 내 구독에서 아래에 언급 된 두 번째 매개 변수 (handleError)로 이동합니다.

.subscribe(success, handleError)

어떤 제안?


map()연산자 내부에 오류를 던지면 됩니다. RxJS의 모든 콜백은 try-catch 블록으로 래핑되어 있으므로 포착 된 다음 error알림으로 전송됩니다 .

즉, 아무것도 반환하지 않고 오류를 던집니다.

map(res => { 
  if (res.bearerToken) {
    return this.saveJwt(res.bearerToken); 
  } else {
    throw new Error('Valid token not returned');
  }
})

throwError()(구 Observable.throw()RxJS 5)을 그냥 보내는 있다는 관측 error통지를하지만 map()당신이 돌아하든 상관하지 않습니다. Observable을 반환하더라도 알림 map()으로 전달됩니다 next.

마지막으로, 아마도 사용할 필요가 없습니다 .catchError()(이전 catch()RxJS 5). 오류가 발생할 때 부작용을 수행해야하는 경우 예를 들어 tap(null, err => console.log(err))(이전 do()RxJS 5) 를 사용하는 것이 좋습니다 .

2019 년 1 월 : RxJS 6 업데이트


throw new Error()관찰 할 수없는 것처럼 느껴진다면 다음 을 사용할 수 있습니다 switchMap.

// RxJS 6+ syntax
this.httpPost.pipe(switchMap(res => { 
   if (res.bearerToken) {
      return of(this.saveJwt(res.bearerToken)); 
   } 
   else {
      return throwError('Valid token not returned');
   }
});

또는 더 간결하게 :

this.httpPost.pipe(switchMap(res => (res.bearerToken) ? 
                                    of(this.saveJwt(res.bearerToken)) : 
                                    throwError('Valid token not returned')
));

동작은 동일하며 구문이 다릅니다.

You're literally saying 'switch' from the http observable in the pipe to a different observable, which is either just 'wrapping' the output value, or a new 'error' observable.

Don't forget to put of or you'll get some confusing error messages.

Also the beauty of 'switchMap' is that you can return a whole new 'chain' of commands if you wanted to - for whatever logic needs to be done with saveJwt.


Even though this question is already answered, I'd like to share my own approach (even though its only slightly different from above).

I would decide what is returned separate from the mapping and vice versa. I'm not sure what operator is best for this so I'll use tap.

this.httpPost.pipe(
  tap(res => { 
    if (!res.bearerToken) {
      throw new Error('Valid token not returned');
    }
  }),
  map(res => this.saveJwt(res.bearerToken)),
);

참고URL : https://stackoverflow.com/questions/43199642/how-to-throw-error-from-rxjs-map-operator-angular

반응형