web-dev-qa-db-ja.com

タイプ 'void'は、タイプ 'ObservableInput <{}>'に割り当てることができません

TS 2.2.2に移行した後、このエラーがポップアップし始めたので、それが問題だと思います...コードは動作を停止しませんでしたが、今はそのエラーを受け取り、空のオブザーバブルを返すなどのいくつかのことを試みました、再スローされた例外をキャッチしてオブジェクトを返す場合、何も機能していないように見えます。なぜ今これが起こっているのですか?例外を再スローし、復帰を期待していないことを理解してはいけませんか?エラーを誤解していますか?

これは完全なエラーの説明です:

enter image description here

完全なコードは次のとおりです。

return request
    .map((res: Response) => res.json())
    .catch((error: any) => {
        // todo: log?

        if (error.status == 500) {
            this.alertService.showError(error.statusText);
        } else if (error.status == 588) {
            this.alertService.showAlert(error.statusText);
        }

        Observable.throw(error.statusText);
    });

Observableを返そうとしましたが、ラッパーメソッドはT型の戻り値を期待しています。これは、デシリアライズされた要求(map(...))の戻り値です。 throwを返すと、これがエラーになります。

[ts]タイプ 'Observable'はタイプ 'T'に割り当てられません

私は使用しています:

  • Angular4
  • TypeScript 2.2.2
39
eestein

observableを返す必要があります

 return request
    .map((res: Response) => res.json())
    .catch((error: any) => {
        // todo: log?

        if (error.status == 500) {
            this.alertService.showError(error.statusText);
        } else if (error.status == 588) {
            this.alertService.showAlert(error.statusText);
        }

        return Observable.throw(error.statusText);
    });

以下のような矢印関数を使用せずにcatchを呼び出す場合があります

getUserList() {
    return this.http.get(this.constURL + '/api/url/here', this.headerOptions)
    .catch(this.handleError);
}

handleError(error: Response) {
    if (error.status == 500) {      
      this.router.navigate(['/login']);
    } else {
      return Observable.throw(error);
    }
}

それからのエラーを与える

エラーTypeError:未定義のプロパティ 'navigate'を読み取れず、これを取得できません

HandleError関数では、このオブジェクトにアクセスできないためです。this.routerをコンソールすると、未定義になります。このオブジェクトは機能せず、利用可能なすべてのメソッドをルーターに取得できません。

以下のように矢印機能を使用する必要があります

getUserList() {
    return this.http.get(this.constURL + '/api/url/here', this.headerOptions)
    .catch(error => { 
      return this.handleError(error);
    });
}

handleError(error: Response) {
    if (error.status == 500) {      
      this.router.navigate(['/login']);
    } else {
      return Observable.throw(error);
    }
}

また、handlerError関数の戻り値に言及していない場合は、次のようにエラーを再度スローします

型 '(error:any)=> void'の引数は型のパラメーターに代入できません

そのため、handlerError関数の戻り値を入力する必要があります。

詳細については here を確認してください。彼は、考えられるすべてのエラーとその解決策についてコードを非常によく説明してくれました。

7

これは、RXJS 6でのangular 6に対する答えです。リクエスト関数では、これは次のようになります。 catchcatchErrorに置き換えられ、Observable.throwthrowErrorになりました。また、RXJS 6では、パイプを使用して、以前のドットチェーンの代わりに、実行する一連の機能を結合します。

//In your service

getData(url: string): Observable<any> {
    let options = this.getHTTPOptions();
    return this.http.get<any>(url, options).pipe(
          catchError( (err: any, caught: Observable<any>) => { return 
        throwError(this.generalErrorHandler(err, caught)) } ) );
}

その後、エラーハンドラを使用できます。重要なのは、上記のreturn関数の両方でキーワードcatchErrorを指定し、ハンドラーでエラーを返すことです。矢印(=>)を使用すると、呼び出し関数のコンテキストをエラーハンドラーに渡すことができます。つまり、this.router.navigate(['someroute']);(サービスにルーターをインポートしている場合)

//In your service

  generalErrorHandler(error: any, caught: Observable<any>): Observable<any> {
    console.log('error caught: ', error);
    if( error.error.status == "INVALID_TOKEN" || error.error.status == "MAX_TOKEN_ISSUE_REACHED"){
      console.log('token has expired');
      this.logout();
      return error;
    }
    return error;
  }

これを機能させるためのキーのインポート:

//Imports for the service

import { HttpClient, HttpHeaders, HttpErrorResponse } from '@angular/common/http';
import { Http, Response } from '@angular/http';
import { catchError, map } from 'rxjs/operators';
import { Observable, throwError, of} from 'rxjs';

最後に、データを取得するリクエストをサブスクライブします。

//In your component, don't forget to import your service

let response$ = this.someService.getData('url here');
response$.subscribe( 
    data => { console.log('do stuff to data here', data); },
    err => { console.log("couldn't get data, maybe show error to user"); },
    () => { console.log('function that is called upon finish'); }
);
5
Josh Dando