[angular] 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). 오류가 발생했을 때 부작용을 수행해야하는 경우 예를 들어 RxJS 5의 tap(null, err => console.log(err))이전 버전 을 사용하는 것이 좋습니다 do().

2019 년 1 월 : RxJS 6 업데이트


답변

throw new Error()관찰 할 수없는 것처럼 느껴진다면 대신 throwError(...)with switchMap를 사용할 수 있습니다 map(차이가 switchMap새로운 관찰 가능 항목을 반환 함).

// this is the import needed for throwError()
import { throwError } from 'rxjs';


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

또는 더 간결하게 :

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

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

당신은 말 그대로 파이프에서 관찰 가능한 http에서 다른 관찰 가능한 것으로 ‘전환’이라고 말하고 있는데, 이는 출력 값을 ‘래핑’하거나 새로운 ‘오류’관찰 가능한 것입니다.

입력하는 것을 잊지 마십시오. 그렇지 않으면 of혼란스러운 오류 메시지가 표시됩니다.

또한 ‘switchMap’의 장점은 .NET을 사용하여 수행해야하는 논리에 대해 원하는 경우 완전히 새로운 ‘체인’명령을 반환 할 수 있다는 것입니다 saveJwt.


답변

이 질문에 대한 답변은 이미 있지만 저의 접근 방식을 공유하고 싶습니다 (위와 약간만 다를지라도).

매핑과 별도로 반환되는 항목을 결정하고 그 반대의 경우도 마찬가지입니다. 어떤 연산자가 가장 적합한 지 잘 모르겠으므로 tap.

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


답변