web-dev-qa-db-de.com

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

Ich versuche, map von einem Serviceaufruf abzurufen, erhalte jedoch eine Fehlermeldung . Betrachtetes subscribe ist nicht in Winkel 2 definiert. und es wurde gesagt, dass wir zum Abonnieren aus den Betreibern zurückkehren müssen. Ich habe auch Rückmeldungen.

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
25
Aakash Thakur

In Ihrem Beispielcode erhalten Sie von Ihrem Operator map zwei Rückrufe, wenn er nur einen Rückruf 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 catch und throw importieren.

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

EDIT: Beachten Sie, dass Sie durch die Rückgabe von Observable.throw in Ihrem catch-Handler den Fehler nicht wirklich erfassen - er wird immer noch zur Konsole angezeigt.

14
snorkpete

In meinem Fall trat der Fehler nur bei e2e-Tests auf. Es wurde durch throwError in meinem AuthenticationInterceptor verursacht.

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

Falsch:

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

Richtig:

import { throwError } from 'rjxs';

Hier der vollständige Code des Interceptors:

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

Sie geben ein Observable zurück, während Ihr Code nur einen Boolean zurückgibt. Sie müssen also wie folgt verwenden

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

Wenn Sie in Ihrem Fall einen anderen gemeinsamen Dienst checkservice verwenden, können Sie einfach verwenden 

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

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

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

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

7
Aravind

Wenn Ihre Funktion erwartet, einen booleschen Wert zurückzugeben, führen Sie einfach Folgendes aus:

  1. Einführen:
import { Observable } from 'rxjs/Observable';
  1. Dann
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.of(false);
           })
 }

Ich hatte vergessen, die andere beobachtbare in pipe(switchMap( zurückzugeben

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

Beim Versuch, einen Benutzer mit JSON-Web Token zu authentifizieren, ist dieses Problem aufgetreten. In meinem Fall hängt es mit dem Interceptor für die Authentifizierung zusammen.

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

Stellen Sie sicher, dass Ihr Interceptor Folgendes enthält:

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

Und dass Sie {'No-Auth':'True'} zur Anfrage Ihrer Kopfzeile wie folgt angeben: 

  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

Kann durch ein Komma (,) in einem RxJS pipe(...) ausgelöst werden

Das Kompilieren wird dieses zusätzliche Komma am Ende nicht fangen:

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

Es wird zu einem "unsichtbaren" undefined-Operator, der die gesamte Pipe verschraubt und zu einer sehr verwirrenden Fehlermeldung führt - die in diesem Fall nichts mit meiner eigentlichen Logik zu tun hat.

0
Simon_Weaver

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

Ich erhalte den gleichen Fehler beim Versuch, eine Dienstvariable von ihrem Konstruktor aus zu initialisieren, indem ich über http.get und . Subscribe () eine entfernte API aufrufe

Nach vielen Tests ohne zu verstehen, was das Problem war, habe ich es endlich verstanden: Meine Anwendung hatte Authentifizierung und ein HttpInterceptor, und ich habe versucht, den Dienst zu initialisieren, der eine öffentliche API-Methode mit http aufruft. get (...) without 'No-Auth' headers. 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 :(

0
tomasofen

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

0
Rakesh Pandey

Ich habe dieselbe genaue Fehlermeldung, während ich meinen Gerätetest durchführte und nach dem Sprechen meiner Dienste eine beobachtbare Ausnahme auslöste.

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

Tatsächlicher Code, der den Dienst aufruft, und subscribe, um Daten abzurufen. Beachten Sie, dass catch den 400-Fehler behandeln soll.

     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 im Service

  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 sie alle erforderlichen Methoden enthält.

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

Der obige Code ist okey, aber als ich versuchte, die Catch/Error-Bedingung durch Übergeben von Observable.throw({}) zu testen, wurde mir der Fehler angezeigt, da er erwartet hatte, dass Response vom Dienst zurückgegeben wurde.

Unterhalb des Service-Spottes gab ich 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 exakt erwartete Funktion in meinem Rückkehrobjekt replizierte, anstatt einen Wert vom Typ Response 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
0
Aniruddha Das