101 votes

TypeError: vous avez fourni un objet non valide pour lequel un flux était attendu. Vous pouvez fournir un objet Observable, Promise, Array ou Iterable.

J'essaie de map d'un appel de service mais j'obtiens une erreur. Regardé souscrire n'est pas défini dans angular 2? et il a dit que pour s'abonner, nous devons revenir de l'intérieur des opérateurs. J'ai aussi des déclarations de retour.

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

Journal d'erreur:

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

46voto

Stevy Points 155

Dans mon cas, l'erreur s'est produite uniquement lors des tests e2e. Cela était dû à throwError dans mon AuthenticationInterceptor.

Je l'ai importé à partir d'une source incorrecte car j'ai utilisé la fonctionnalité d'importation de WebStorm. J'utilise RxJS 6.2.

Faux:

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

Correct:

 import { throwError } from 'rjxs';
 

Voici le code complet de l'intercepteur:

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

21voto

Snorkpete Points 75

Dans votre exemple de code, vous avez votre map opérateur ayant reçu deux rappels, quand il ne doit être en recevoir un. Vous pouvez déplacer votre code de gestion d'erreur pour vos prises de rappel.

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

Vous devez également importer l' catch et throw opérateurs.

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

EDIT: Notez qu'en retournant Observable.throwdans votre gestionnaire catch, vous n'aurez pas fait de capture de l'erreur - il encore de la surface de la console.

13voto

Si votre fonction s'attend à renvoyer un booléen, procédez comme suit:

  1. Importation:
 import { of, Observable } from 'rxjs';
import { map, catchError } from 'rxjs/operators';
 
  1. ensuite
 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);
      })
)}
 

10voto

Aravind Points 21523

Vous retournez un observable alors que votre code ne renvoie qu'un booléen. Donc, vous devez utiliser comme ci-dessous

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

Si vous utilisez un autre service commun checkservice dans votre cas, vous pouvez simplement utiliser

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

Cela rendra votre fonction checkLogin() avec le type de retour comme nul

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

et vous pouvez utiliser this.checkService pour vérifier votre condition

2voto

Badis Merabet Points 2220

J'ai été confronté à ce problème lors de la tentative d'authentification d'un utilisateur à l'aide d'un jeton Web JSON. dans mon cas, c'est lié à l'intercepteur d'authentification.

L'envoi d'une demande d'authentification d'un utilisateur ne doit pas obligatoirement fournir de jeton puisqu'il n'existe pas encore.

Vérifiez que votre intercepteur inclut ceci:

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

Et que vous fournissiez {'No-Auth':'True'} à la demande de votre en-tête comme ceci:

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X