web-dev-qa-db-ja.com

TypeError:ストリームが予期される場所に無効なオブジェクトを提供しました。 Observable、Promise、Array、またはIterableを提供できます

サービス呼び出しからmapを実行しようとしていますが、エラーが発生しています。 サブスクライブは角度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
36
Aakash Thakur

サンプルコードでは、map演算子が2つのコールバックを受け取りますが、コールバックを受け取るのは1つだけである必要があります。エラー処理コードをcatchコールバックに移動できます。

checkLogin():Observable<boolean>{
    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);
                       })
   }

catchおよびthrow演算子もインポートする必要があります。

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

EDIT:キャッチハンドラーでObservable.throwを返すことにより、実際にエラーをキャプチャしないことに注意してください-コンソールに表示されます。

15
snorkpete

私の場合、エラーはe2eテスト中にのみ発生しました。 AuthenticationInterceptorのthrowErrorが原因でした。

WebStormのインポート機能を使用したため、間違ったソースからインポートしました。 RxJS 6.2を使用しています。

違う:

import { throwError } from 'rjxs/internal/observable/throwError';

正しい:

import { throwError } from 'rjxs';

ここでインターセプターの完全なコード:

import { Injectable } from '@angular/core';
import { HttpErrorResponse, HttpEvent, HttpHandler, HttpInterceptor, HttpRequest } from '@angular/common/http';
import { Observable, throwError } from 'rxjs';
import { catchError } from 'rxjs/operators';

@Injectable()
export class AuthenticationInterceptor implements HttpInterceptor {

  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    const reqWithCredentials = req.clone({withCredentials: true});
    return next.handle(reqWithCredentials)
     .pipe(
        catchError(error => {
          if (error.status === 401 || error.status === 403) {
            // handle error
          }
          return throwError(error);
        })
     );
  }
}
12
Stevy

コードがブール値を返すだけのObservableを返しています。以下のように使用する必要があります

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

あなたのケースで別の共通サービスcheckserviceを使用している場合は、単に使用することができます

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

これにより、戻り値の型がvoidのcheckLogin()関数が作成されます

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

this.checkServiceを使用して状態を確認できます

7
Aravind

関数がブール値を返すことを期待している場合は、次のようにします。

  1. インポート:
import { of, Observable } from 'rxjs';
import { map, catchError } from 'rxjs/operators';
  1. それから
checkLogin(): Observable<boolean> {
  return this.service.getData()
    .pipe(
      map(response => {
        this.data = response;
        this.checkservice = true;
        return true;
      }),
      catchError(error => {
        this.router.navigate(['newpage']);
        console.log(error);
        return of(false);
      })
)}

pipe(switchMap(で他のオブザーバブルを返すのを忘れていました

this.dataService.getPerson(personId).pipe(
  switchMap(person => {
     //this.dataService.getCompany(person.companyId); // return missing
     return this.dataService.getCompany(person.companyId);
  })
)
2
FindOutIslamNow

JSON Web Tokenを使用してユーザーを認証しようとすると、この問題に直面していました。私の場合、認証インターセプターに関連しています。

ユーザーを認証するリクエストを送信する場合、トークンはまだ存在しないため、トークンを提供する必要はありません。

インターセプターにこれが含まれていることを確認します。

if (req.headers.get('No-Auth') == "True")
            return next.handle(req.clone());

そして、次のようにヘッダー要求に{'No-Auth':'True'}を提供します。

  authenticateUser(user): Observable<any> {
    const headers = new HttpHeaders({'No-Auth':'True'});
    headers.append('Content-Type', 'application/json');
    return this.httpClient.post(`${this.apiEndpoint}/auth/authenticate`, user, {headers: headers});
  }
1
Badis Merabet

RxJS pipe(...)の浮遊コンマ(,)によってトリガーできます

コンパイルは最後にこの余分なコンマをキャッチしません:

pipe(first(), map(result => ({ event: 'completed', result: result}),);

これは「見えない」undefined演算子になり、パイプ全体を台無しにして、非常にわかりにくいエラーメッセージにつながります。この場合、実際のロジックとは関係ありません。

0
Simon_Weaver

同じエラーを探してここに到着したので、これを書きました。これは将来誰かに役立つかもしれません。

Http.getおよび。subscribe()を介してリモートAPIを呼び出すコンストラクターからサービス変数を初期化しようとすると、同じエラーが発生します。

問題が何であるかを理解せずに多くのテストを行った後、私は最終的にそれを取得しました:私のアプリケーションには認証とHttpInterceptorがあり、http。 get(...)'No-Auth'ヘッダーなし。ここのようにそれらを追加し、問題を解決しました:

getData() {
var reqHeader = new HttpHeaders({ 'Content-Type': 'application/x-www-urlencoded','No-Auth':'True' });    
return this.http.get(environment.urlApi.Literales, { headers: reqHeader });  
}

なんて頭痛:(

0
tomasofen

私の場合、Angular-5では、メソッドにアクセスしてデータをサブスクライブしていたサービスファイルはインポートされませんでした。サービスファイルをインポートした後、正常に機能しました。

0
Rakesh Pandey

サービスをモックした後、ユニットテストを実行し、観測可能な例外をスローしている間も、まったく同じエラーメッセージが表示されます。

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をモックし、観測可能なデータを返します。その中には、必要なすべてのメソッドが含まれているため、そのデータは正常です。

 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型の値を渡すのではなく、返されるオブジェクトで期待される正確な関数を複製することで修正しました。

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
Aniruddha Das