web-dev-qa-db-ja.com

Angular2で観察可能なエラーを手動でスローするにはどうすればよいですか?

私はangular2アプリに取り組んでおり、以下のようにHTTpを介して休憩通話をしています:

login(email, password) {
    let headers = new Headers();
    headers.append('Content-Type', 'application/x-www-form-urlencoded');
    let options = new RequestOptions({ headers: headers });
    let body = `identity=${email}&password=${password}`;
    return this.http.post(`${this._configService.getBaseUrl()}/login`, body, options)
    .map((res: any) => {
        let response: any = JSON.parse(res._body);
        if (response.success == 0) {
          Observable.throw(response);  // not working
        } else if (response.success == 1) {
          console.log('success');
          localStorage.setItem('auth_token', 'authenticated');
          this.loggedIn = true;
          return response;
        }
    });
}

基本的に、サブスクライブ呼び出しでコンポーネントに応答とエラーを取得させます。

つまり.

this._authenticateService.login(this.loginObj['identity'],this.loginObj['password']).subscribe(
  (success)=>{      
    this.credentialsError=null;  
    this.loginObj={};  
    this._router.navigate(['dashboard']);    
  },
  (error)=>{
    console.log(error);        
    this.credentialsError=error;     
  }
);

しかし、私のAPIはそのように定義されたIDとして常に成功を返します。

したがって、response.success == 0の場合にエラーメッセージをスローする方法を知りたいので、サブスクライブコールバックのエラー引数内でアクセスできます。

38
Bhushan Gadekar
if (response.success == 0) {
   throw Observable.throw(response);  
 } 

rxjs 6の編集

if (response.success == 0) {
   throw throwError(response);  
 } 
51
Jorawar Singh

rxjs 6

import { throwError } from 'rxjs';

if (response.success == 0) {
  return throwError(response);  
}

rxjs 5

import { ErrorObservable } from 'rxjs/observable/ErrorObservable';

if (response.success == 0) {
  return new ErrorObservable(response);  
}

ErrorObservableで返すものはあなた次第です

60
CapK

rxjs 6を使用

import { throwError } from 'rxjs';
throwError('hello');
9
hajaniain

rxjs 5

どちらか

throw response;

または

throw Observable.throw(response);
9

通常、エラーをスローしているときは、問題が発生した正確な瞬間にエラーをスローし、すぐにそれを上げたいと思うでしょうが、これは常にそうであるとは限りません。

たとえば、timeoutWith()演算子があります。これはおそらく、これを行う必要がある最も可能性の高い理由の1つです。

results$ = server.getResults().pipe(timeoutWith(10000, ....) )

これには、関数である「エラーファクトリ」が必要です。

 errorFactory = () => 'Your error occurred at exactly ' + new Date()

例えば。

results$ = server.searchCustomers(searchCriteria).pipe(timeoutWith(10000, 
              () => 'Sorry took too long for search ' + JSON.stringify(searchCriteria)) )

timeoutWithを使用すると、実際のサーバー応答が返されないことに注意してください。したがって、サーバーが特定のエラーを返した場合、それは表示されません。この例はデバッグに非常に役立ちますが、上記の例を使用する場合は、エンドユーザーにエラーを表示しないでください。

エラーファクトリは、実際のエラーが発生するまでコードを評価しないため便利です。したがって、実際にエラーが最終的に必要になったときに実行される「高価な」またはデバッグ操作を内部に配置できます。

「ファクトリ」を使用して、タイムアウト以外の場所でエラーを作成する必要がある場合は、次を使用できます。

 EMPTY.pipe(throwIfEmpty(errorFactory)) 
0
Simon_Weaver

Catch演算子を使用します

this.calcSub = this.http.post(this.constants.userUrl + "UpdateCalculation", body, { headers: headers })
   .map((response: Response) => {
      var result = <DataResponseObject>response.json();
         return result;
   })
   .catch(this.handleError)
   .subscribe(
      dro => this.dro = dro,
      () => this.completeAddCalculation()
   );

そして、このようなエラーを処理します:

private handleError(error: Response) {
    console.error(error); // log to console instead
    return Observable.throw(error.json().error || 'Server Error');
}
0
John Baird

私の問題のほとんどはインポートに関連していたので、ここに私のために働いたコードがあります...

import {_throw} from 'rxjs/observable/throw';
login(email, password) {
...
    return this.http.post(`${this._configService.getBaseUrl()}/login`, body, options)
    .map((res: any) => {
...
        if (response.success == 0) {
           _throw(response);  
        } else if (response.success == 1) {
...
        }
    });
}

次のようなエラーに直面している場合、これが解決策になります...

ERROR TypeError:WEBPACK_IMPORTED_MODULE_2_rxjs_Observable。Observable.throwは関数ではありません

0
Ajay