TypeErrorが発生しました。ストリームが期待されるところを、無効なオブジェクトを提供しました。Observable、Promise、Array、Iterableのいずれかを指定できます。

サービスコールから map を実行しようとしていますが、エラーが発生します。 https://stackoverflow.com/questions/41995647/subscribe-is-not-defined-in-angular-2 を見てみると、サブスクライブするためには、演算子の中からリターンする必要があると書かれていました。returnステートメントもあります。

以下が私のコードです。

checkLogin(): Observable<boolean> {
    return this.service.getData()
        .map(
            response => {
                this.data = response;                            
                this.checkservice = true;
                return true;
            },
            error => {
                // debugger;
                this.router.navigate(['newpage']);
                console.log(error);
                return false;
            }
        )
        .catch(e => {
            return e;
        });
}

エラーログです。

TypeError: You provided an invalid object where a stream was expected. You can provide an Observable, Promise, Array, or Iterable

あなたのサンプルコードでは、map演算子が1つのコールバックしか受け取らないはずなのに、2つのコールバックを受け取っています。エラー処理のコードをcatchコールバックに移すことができます。

checkLogin():Observable{
    return this.service.getData()
                       .map(response => {  
                          this.data = response;                            
                          this.checkservice=true;
                          return true;
                       })
                       .catch(error => {
                          this.router.navigate(['newpage']);
                          console.log(error);
                          return Observable.throw(error);
                       })
   }

また、catchthrowの演算子をインポートする必要があります。

import 'rxjs/add/operator/catch';
import 'rxjs/add/observable/throw';

EDIT: キャッチハンドラで Observable.throw を返すことで、実際にはエラーを捕捉することはできませんが、コンソールにはエラーが表示されます。

解説 (3)

あなたのコードはObservableを返していますが、あなたのコードはただのbooleanを返しています。そのため、以下のようにする必要があります。

.map(response => response.json())

もし、他の一般的なサービス checkservice を使用している場合は、単に

this.service.getData().subscribe(data=>console.log(data));

これにより、checkLogin() 関数の戻り値を void にすることができます。

 checkLogin():void{
      this.service.getData()
            .map(response => {  
                           this.data = response;                            
                           this.checkservice=true;
             }).subscribe(data=>{ });

そして、this.checkService を使って条件をチェックすることができます。

解説 (6)

ユニットテストを行っているときに、まったく同じエラーメッセージが表示され、サービスをモックした後に観察可能な例外が発生しました。

私はObservable.throwに正確な関数とフォーマットを渡すことで解決しました。

サービスを呼び出し、データを取得するために subscribe を行う実際のコードです。400 エラーを処理するための catch に注目してください。

     this.search(event).catch((e: Response) => {
        if (e.status === 400) {
          console.log(e.json().message);
        } else if (e.url) {
          console.log('HTTP Error: ' + e.status + ' ' + e.statusText,
            'URL: ' + e.url, 'Info: ' + e.json().message));
        }
      }).finally(() => {
        this.loading = false;
      }).subscribe((bData) => {
        this.data = bData;
      });

サービス内部のコード

  search() {
    return this.someService.getData(request)
       .do((r) => {
          this.someService.defaultHeaders.delete('skipAlert');
          return r;
        })
      .map((r) => {
          return r.businessObjectDataElements.length && r.businessObjectDataElements || null;
        });
  }

ユニットテスト

SomeServiceをモックしてobservableデータを返してみましたが、必要なメソッドがすべて入っているので問題ありません。

 someServiceApi = fixture.debugElement.injector.get(SomeService);
 spyOn(someServiceApi, 'getData').and.returnValue(Observable.of({}));

上記のコードは問題ありませんが、Observable.throw({})を渡してキャッチ/エラー条件をテストしようとしたとき、サービスからResponseタイプのリターンを期待していたため、エラーが表示されました。

そのため、以下のサービスのモックリターンではエラーが発生していました。

someServiceApi.getData
  .and.returnValue(Observable.throw(new Response({status: 400, body: [], message: 'not found error'})));

そこで私は、Response型の値を渡すのではなく、期待される関数をそのままreturnオブジェクトで再現することで修正しました。

someServiceApi.getData
  .and.returnValue(Observable.throw({status: 400, json: () => { return {message: 'not found error'}}, body: []}));
// see `json: () => { return {message: 'not found error'}}` inside return value
解説 (0)