TypeError: You provided an invalid object where a stream was expected. You can provide an Observable, Promise, Array, or Iterable
In my case the error occurred only during e2e tests. It was caused by throwError
in my AuthenticationInterceptor.
I imported it from a wrong source because I used WebStorm's import feature. I am using RxJS 6.2.
Wrong:
import { throwError } from 'rxjs/internal/observable/throwError';
Correct:
import { throwError } from 'rxjs';
Here the full code of the interceptor:
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); }) ); }}
In your example code, you have your map
operator receiving two callbacks, when it should only be receiving one. You can move your error handling code to your catch callback.
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); }) }
You'll need to also import the catch
and throw
operators.
import 'rxjs/add/operator/catch';import 'rxjs/add/observable/throw';
EDIT: Note that by returning Observable.throw
in your catch handler, you won't actually capture the error - it will still surface to the console.
If your function is expecting to return a boolean, just do this:
- Import:
import { of, Observable } from 'rxjs';import { map, catchError } from 'rxjs/operators';
- Then
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); }))}