TypeError: Sie haben ein ungültiges Objekt angegeben, für das ein Stream erwartet wurde. Sie können ein Observable, Promise, Array oder Iterable bereitstellen

74

Ich versuche es mapvon einem Serviceabruf aus, erhalte aber eine Fehlermeldung. Betrachtet man Abonnieren ist nicht in Winkel 2 definiert? und es hieß, dass wir, um uns anzumelden, aus dem Inneren der Betreiber zurückkehren müssen. Ich habe auch Rücksendungen.

Hier ist mein Code:

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

Fehlerprotokoll:

TypeError: You provided an invalid object where a stream was expected. You can provide an Observable, Promise, Array, or Iterable
Aakash Thakur
quelle
1
Ich habe ein ähnliches Problem erhalten: Es ist You provided 'undefined' where a stream was expected. You can provide an Observable, Promise, Array, or Iterable.jedoch passiert, während mein Server ausgeführt wurde und ich zwischen Zweigen gewechselt habe. Alles was ich tun musste war meinen Server neu zu starten und es ging weg.
Tylerlindell
1
@AakashThakur Ihr Rückgabetyp ist Observable<boolean>. Daher sollten alle Ihre return-Anweisungen ein Observable of boolean zurückgeben. Wrap return Anweisung mit of(). Beispiel 1: return of(false)Beispiel 2:return of(e)
Saddam Pojee

Antworten:

35

In meinem Fall trat der Fehler nur bei e2e-Tests auf. Es wurde von throwErrorin meinem AuthenticationInterceptor verursacht.

Ich habe es aus einer falschen Quelle importiert, weil ich die Importfunktion von WebStorm verwendet habe. Ich benutze RxJS 6.2.

Falsch:

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

Richtig:

import { throwError } from 'rxjs';

Hier der vollständige Code des Abfangjägers:

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);
        })
     );
  }
}
Stevy
quelle
Möglicherweise befinden sich zwei Versionen gleichzeitig in Ihrem Projekt, wenn Sie gerade mit der rxjs-kompatiblen Bibliothek auf RxJS 6 umsteigen.
Stevy
2
Ich hatte einen ähnlichen Fall, mein Abfangjäger führte den next.handle(request)Anruf nur in einem Wenn durch. Das Abfangen einer Anfrage und das Nichtaufrufen des Handles nachher führt zu dieser Nachricht.
Bancarel Valentin
Ich hatte ein ähnliches Problem, das intervalvon der falschen Stelle herein kam rxjs. Dies war eine äußerst hilfreiche Antwort, danke!
Alexander Nied
In meinem Fall hatte ich nur retrunund nicht. return throwError(error)Danke für die Antwort.
Utkarsh
21

In Ihrem Beispielcode maperhält Ihr Operator zwei Rückrufe, wenn er nur einen erhalten soll. Sie können Ihren Fehlerbehandlungscode in Ihren Catch-Rückruf verschieben.

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

Sie müssen auch die Operatoren catchund importieren throw.

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

BEARBEITEN: Beachten Sie, dass Observable.throwSie den Fehler bei der Rückkehr in Ihren Catch-Handler nicht erfassen - er wird weiterhin in der Konsole angezeigt.

Schnorchel
quelle
Aber ich bekomme jetzt diesen Fehler:Error: Uncaught (in promise): [object ProgressEvent]
Aakash Thakur
Sie können versuchen, die Observable.throwZeile in zu ändern Observable.of (und den Import einzuschließen). Dadurch wird Ihr Observable den Fehler ausgeben, aber es wird nicht als Fehler behandelt. (Im Grunde schlucken wir den Fehler irgendwie / aber nicht ganz). Überprüfen Sie, ob der Fehler dadurch von der Konsole entfernt wird. Wenn dies der Fall ist, zeigt es auf die fehlgeschlagene Methode getData ()
snorkpete
10

Wenn Ihre Funktion einen Booleschen Wert erwartet, gehen Sie wie folgt vor:

  1. Importieren:
import { of, Observable } from 'rxjs';
import { map, catchError } from 'rxjs/operators';
  1. Dann
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);
      })
)}
Daniel Eduardo Delgado Diaz
quelle
9

Sie geben ein Observable zurück, wobei Ihr Code nur einen Booleschen Wert zurückgibt. Sie müssen also wie folgt verwenden

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

Wenn Sie checkservicein Ihrem Fall einen anderen allgemeinen Dienst verwenden , können Sie diesen einfach verwenden

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

Dadurch wird Ihre checkLogin()Funktion mit dem Rückgabetyp ungültig

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

und Sie können verwenden this.checkService, um Ihren Zustand zu überprüfen

Aravind
quelle
Ich muss ein zurückgeben, Observable<boolean>weil ich es in einer anderen Funktion verwenden muss.
Aakash Thakur
Was gibt Ihre Funktion getData () zurück?
Aravind
getData () kehrt zurück[object Object]{id: "1234", isAdmin: false, userName: "Lama", newid: Array[1]}
Aakash Thakur
Tut mir Leid, Bruder. Ich bin nicht.
Aakash Thakur
Ich kann meinen Bildschirm nicht reproduzieren oder Ihnen zeigen, da es sich nicht um ein Heimprojekt handelt, sondern um etwas Vertrauliches, und dies ist nur ein Teil, bei dem ich Probleme hatte.
Aakash Thakur
5

Ich vergaß, den anderen Beobachtbaren zurückzugeben pipe(switchMap(

this.dataService.getPerson(personId).pipe(
  switchMap(person => {
     //this.dataService.getCompany(person.companyId); // return missing
     return this.dataService.getCompany(person.companyId);
  })
)
FindOutIslamNow
quelle
Ich habe das switchMapin meinen Unit-Tests zurückgegebene Observable mit dem gleichen Ergebnis nicht richtig verspottet .
Kevin Beal
2

Kann durch ein streunendes Komma ( ,) in einem RxJS ausgelöst werdenpipe(...)

Die Kompilierung erhält dieses zusätzliche Komma am Ende nicht:

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

Es wird zu einem "unsichtbaren" undefinedOperator, der das gesamte Rohr versaut und zu einer sehr verwirrenden Fehlermeldung führt - was in diesem Fall nichts mit meiner tatsächlichen Logik zu tun hat.

Simon_Weaver
quelle
2

Ich hatte das gleiche Problem, das durch den Import der internen Version von 'takeUntil' anstelle der Operatoren Change verursacht wurde

import { takeUntil } from 'rxjs/internal/operators/takeUntil';

zu

import { takeUntil } from 'rxjs/operators';

Dies gilt auch für andere Betreiber

Abdo Driowya
quelle
1

Ich habe dieses Problem beim Versuch, einen Benutzer mithilfe von JSON Web Token zu authentifizieren, festgestellt. In meinem Fall hängt es mit dem Authentifizierungs-Interceptor zusammen.

Das Senden einer Anforderung zur Authentifizierung eines Benutzers muss kein Token bereitstellen, da es noch nicht vorhanden ist.

Überprüfen Sie, ob Ihr Abfangjäger Folgendes enthält:

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

Und das geben Sie {'No-Auth':'True'}auf die Anfrage Ihres Headers wie folgt an:

  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});
  }
Badis Merabet
quelle
1

Ein Hinweis für alle, die dies erleben. Dies kann passieren, wenn a switchMapkeinen beobachtbaren Rückgabewert erhält (wie null ). Fügen Sie einfach einen Standardfall hinzu, damit immer ein Observable zurückgegeben wird.

        switchMap((dateRange) => {
          if (dateRange === 'Last 24 hours') {
            return $observable1;
          }
          if (dateRange === 'Last 7 Days') {
            return $observable2;
          }
          if (dateRange === 'Last 30 Days') {
            return $observable3;
          }
          // This line will work for default cases
          return $observableElse;
        })
Ben Winding
quelle
0

Ich habe dies geschrieben, weil ich hier ankomme und nach dem gleichen Fehler suche, und dies könnte für jemanden in der Zukunft nützlich sein.

Ich erhalte den gleichen Fehler, wenn ich versuche, eine Dienstvariable von ihrem Konstruktor zu initialisieren, indem ich über http.get und .subscribe () eine Remote-API aufrufe.

Nach vielen Tests, ohne zu verstehen, was das Problem war, habe ich es endlich verstanden: Meine Anwendung hatte Authentifizierung und einen HttpInterceptor , und ich habe versucht, den Dienst zu initialisieren, der eine öffentliche API-Methode mit http.get (...) ohne 'No-Auth' aufruft ' Header. Ich habe sie wie hier hinzugefügt und das Problem für mich gelöst:

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

Was für Kopfschmerzen :(

tomasofen
quelle
0

In meinem Fall in Angular-5 wurde keine Servicedatei importiert, von der aus ich auf die Methode zugegriffen und die Daten abonniert habe. Nach dem Importieren der Servicedatei funktionierte dies einwandfrei.

Rakesh Pandey
quelle
0

Dieser Fehler ist bei mir aufgetreten, wenn ich Interceptor verwende. Sie müssen dies in Ihrem Interceptor tun

return next.handle(request).map(event => {
        if (event instanceof HttpResponse) {

        }
        return event;
    },
      catchError((error: HttpErrorResponse) => {
        if (error.status === 401 || error.status === 400) {
          // some logic

        }
Hosam Hemaily
quelle
0

Dieser Fehler ist mir @angular 7 passiert

Sie haben ein ungültiges Objekt angegeben, für das ein Stream erwartet wurde. Sie können ein Observable, Promise, Array oder Iterable bereitstellen.

Der Fehler ist eigentlich selbsterklärend, es heißt somewherein der beobachtbaren ich übergebe das ungültige Objekt. In meinem Fall gab es viele API-Aufrufe, aber alle Aufrufe schlugen aufgrund einer falschen Serverkonfiguration fehl. Ich habe versucht, einen anderen rxjs-Operator zu verwenden map, switchMapaber die Operatoren erhalten undefinierte Objekte.

Überprüfen Sie daher die Eingaben Ihres rxjs-Operators.

Tasnim Reza
quelle
0

Ich hatte auch das gleiche Problem, als ich eine Methode in switchMap aufrief. Anscheinend stellte ich fest, dass wenn wir eine Methode in switchMap verwenden, diese beobachtbar zurückgegeben werden muss.

Ich habe Pipe verwendet, um Observable zurückzugeben, und Map, um Operationen innerhalb von Pipe für einen API-Aufruf auszuführen, den ich innerhalb der Methode ausgeführt habe, anstatt sie zu abonnieren.

Nikhil Kamani
quelle
0

Ich hatte diesen Fehler, wenn es projektübergreifend unterschiedliche RxJS-Versionen gab. Die internen Prüfungen in RxJS schlagen fehl, da es mehrere verschiedene gibt Symbol_observable. Schließlich wirft diese Funktion einmal aufgerufen von einem Abflachungsoperator wie switchMap.

Versuchen Sie, symbolbeobachtbare Elemente an einem Einstiegspunkt zu importieren.

// main index.ts
import 'symbol-observable';
blid
quelle
0

Ich bin nicht sicher, ob dies jemandem helfen wird, aber in meinem Fall weiter oben in meiner Kette, die ich verwendet habe, distinctUntilChangedund eine Ausnahme innerhalb einer Funktion, die sich mit dieser Fehlermeldung manifestierte.

Chris Putnam
quelle
0

Sie erhalten auch die folgende Fehlermeldung, wenn Sie einem Operator, der ein Observable erwartet , z. takeUntil .

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

In meinem Fall habe ich Action fälschlicherweise in meine combinEpics importiert und nicht in Epic ...

Stellen Sie sicher, dass alle Funktionen in Combine Epics epische Funktionen sind

Rahul Shakya
quelle
-1

Ich habe genau die gleiche Fehlermeldung, während ich meinen Komponententest durchgeführt und eine beobachtbare Ausnahme ausgelöst habe, nachdem ich meine Dienste verspottet habe.

Ich habe es gelöst, indem ich die genaue Funktion und das Format übergeben habe Observable.throw.

Tatsächlicher Code, der den Dienst aufruft und subscribeDaten abruft. Beachten Sie dies, catchum den 400Fehler zu beheben .

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

Der Code innerhalb des Dienstes

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

Unit Testing

Ich habe den SomeService verspottet und beobachtbare Daten zurückgegeben, und es ist in Ordnung, da er alle erforderlichen Methoden enthält.

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

Der obige Code ist in Ordnung, aber als ich versuchte, die Catch / Error-Bedingung durch Übergeben zu testen, Observable.throw({})zeigte er mir den Fehler, da er eine Typrückgabe Responsevom Service erwartete .

Die unten stehende Verspottung gab mir diesen Fehler.

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

Also habe ich es korrigiert, indem ich die genau erwartete Funktion in meinem Rückgabeobjekt repliziert habe, anstatt einen ResponseTypwert zu übergeben.

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

In Bezug auf den Fehler "Sie haben ein ungültiges Objekt angegeben, bei dem ein Stream erwartet wurde. Sie können einen Observable-, Promise-, Array- oder Iterable- Fehler angeben."

Dies kann passieren, wenn Sie import { Observable } from 'rxjs' nach (unten) einem Modul / einer Funktion / was auch immer suchen, das es tatsächlich verwendet.

Lösung : Verschieben Sie diesen Import über den Import dieses Moduls.

Neurotransmitter
quelle