TypeError: 您提供了一个预期流的无效对象。您可以提供一个可观察对象、允诺对象、数组对象或可迭代对象

我试图从一个服务呼叫 map,但得到一个错误。 看看 订阅不是定义在角2?,它说,为了订阅,我们需要从运营商内部返回。我也有回报表。

这是我的密码:

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: 您提供了一个预期流的无效对象。您可以提供一个可观察对象、允诺对象、数组对象或可迭代对象

272614 次浏览

You are returning an Observable where as your code returns just a boolean. So you need to use as below

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

If you are using another common service checkservice in your case, you can simply use

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

This will make your checkLogin() function with return type as void

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

and you can use of this.checkService to check your condition

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.throwin your catch handler, you won't actually capture the error - it will still surface to the console.

I have the same exact error message while I was doing my unit test and throwing observable exception after mocking my services.

I resolved it by passing exact function and format inside Observable.throw.

Actual code which calls the service and subscribe to get data. notice that catch to handle the 400 error.

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

The code inside the 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

I have mocked the SomeService and returning observable data and its fine as it have all the required methods inside it.

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

The above code is okey but when when I was trying to test the catch/error condition by passing Observable.throw({}) it was showing me the error as it was expecting Response type return from the service.

So below service mocking return was giving me that error.

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

So I Corrected it by replicating the exact expected function in my return object rather passing a Response type value.

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

If your function is expecting to return a boolean, just do this:

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

I have been facing this issue when trying to authenticate a user using JSON Web Token. in my case it's related to authentication interceptor.

Sending a request to authenticate a user doesn't have to provide a token since it doesn't exist yet.

Check that your interceptor include this:

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

And that you provide {'No-Auth':'True'} to your header's request like this:

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

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

Can be triggered by a stray comma (,) in an RxJS pipe(...)

The compile won't catch this extra comma at the end:

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

It becomes an 'invisible' undefined operator which screws the whole pipe up, and leads to a very confusing error message - which in this case has nothing to do with my actual logic.

I wrote this because I arrive here searching for the same error, and this could be useful for someone in the future.

I get the same error while trying to initialize a service variable from its constructor making a call to a remote API trough http.get and .subscribe()

After many tests without understanding what the problem was, i finally get it: My application had authentication and an HttpInterceptor, and i was trying to initialize the service calling a public API method using http.get(...) without 'No-Auth' headers. I added them like here, and problem solved for me:

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

What a headache :(

In my case in Angular-5, service file was not imported from which i was accessing the method and subscribing the data.After importing service file it worked fine.

I was forgetting to return the other observable in pipe(switchMap(

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

In regard to the "You provided an invalid object where a stream was expected. You can provide an Observable, Promise, Array, or Iterable" error.

This could happen if you import { Observable } from 'rxjs' after (below) some module/function/whatever, which actually uses it.

Solution: move this import above the import of that module.

I had the same issue caused by importing the internal version of 'takeUntil' instead of the operators Change

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

to

import { takeUntil } from 'rxjs/operators';

This happen also for other operators

A hint for anyone experiencing this. This can happen when a switchMap doesn't receive an observable return value (like null). Simply add a default case, so it always returns an observable.

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

this error happened with me when i am using interceptor you have to do this in your interceptor

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


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


}

This error happened to me @angular 7

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

The error is actually self-explanatory, it says somewhere in the observable I pass the invalid object. In my case, there was lots of API call but all the calls were failing because of wrong server configuration. I tried to use map, switchMap, or other rxjs operator but the operators are getting undefined objects.

So double-check your rxjs operator inputs.

I was also facing the same issue when i was calling a method inside switchMap, apparently I found that if we use method inside switchMap it must return observable.

i used pipe to return observable and map to perform operations inside pipe for an api call which i was doing inside method rather than subscribing to it.

I've had this error when there's been different RxJS-versions across projects. The internal checks in RxJS fails because there are several different Symbol_observable. Eventually this function throws once called from a flattening operator like switchMap.

Try importing symbol-observable in some entry point.

// main index.ts
import 'symbol-observable';

I'm not sure if this will help anyone, but in my case further up my chain I was using distinctUntilChanged and an exception inside a function there was manifesting with this error message.

You will get the following error message too when you provide undefined or so to an operator which expects an Observable, eg. takeUntil.

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

In my case I mistakely imported Action into my combineEpics, rather than Epic...

Verify all the functions within combine Epics are epic funcitons

I had a similar error using RXJS in NESTJS.

Error: TypeError: You provided 'undefined' where a stream was expected. You can provide an Observable, Promise, Array, or Iterable. +1ms

In my case I forgot to return an Observable in a switchMap. This caused that no Observable was received in the next RXJS operator or client code.

Once I returned an Observable in the switchMap, the error disappeared.