TypeError:您提供了一个无效的对象,该对象应在其中流。您可以提供一个Observable,Promise,Array或Iterable


74

我正在尝试map从服务呼叫中获取但出现错误。看着subscribe没有在角度2中定义?它说,要订阅,我们需要从运营商内部返回。我也有return语句。

这是我的代码:

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: You provided an invalid object where a stream was expected. You can provide an Observable, Promise, Array, or Iterable

1
我收到了类似的问题:You provided 'undefined' where a stream was expected. You can provide an Observable, Promise, Array, or Iterable.但是这发生在我的服务器运行时,我在分支之间切换。我需要做的就是重启服务器,然后服务器消失了。
tylerlindell

1
@AakashThakur您的返回类型为Observable<boolean>。因此,所有的return语句都应返回一个Observable布尔值。用来包装返回语句of()。范例1:return of(false)范例2:return of(e)
Saddam Pojee

Answers:


35

就我而言,该错误仅在e2e测试期间发生。这是由throwError我的AuthenticationInterceptor引起的。

我从错误的来源导入了它,因为我使用了WebStorm的导入功能。我正在使用RxJS 6.2。

错误:

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

正确:

import { throwError } from 'rxjs';

这里是拦截器的完整代码:

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

如果您正在使用rxjs-compat库过渡到RxJS 6,则您的项目中可能同时有两个版本。
Stevy,

2
我有一个类似的案例,我的拦截器仅next.handle(request)在if中进行调用。因此,截获请求而不进一步调用句柄将导致此消息。
Bancarel Valentin

我有一个类似的问题,是interval从错误的地方带进来的rxjs。这是一个非常有用的答案,谢谢!
亚历山大·尼德

就我而言,我只有 retrun而没有。return throwError(error)谢谢您的回答。
乌特卡什

21

在示例代码中,您的map操作员将只接收一个回调,而接收两个回调。您可以将错误处理代码移至catch回调。

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

您还需要导入catchthrow运算符。

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

编辑: 请注意,通过返回Observable.throwcatch处理程序,您实际上不会捕获错误-它仍会浮现到控制台。


但是我现在收到此错误:Error: Uncaught (in promise): [object ProgressEvent]
Aakash Thakur

您可以尝试将Observable.throw行更改为Observable.of (并包括导入)。那将导致您的观察对象发出错误,但是不会将其视为失败。(基本上,我们有点/很不正确地吞并了错误)。查看是否可以从控制台中删除错误。如果是这样,则它指向失败的getData()方法
snorkpete

10

如果您的函数期望返回布尔值,请执行以下操作:

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

9

您将返回一个Observable,其中代码返回的只是一个布尔值。所以你需要如下使用

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

如果您要使用其他常用服务checkservice,则只需使用

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

这将使您的checkLogin()函数的返回类型为void

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

您可以使用this.checkService来检查您的状况


我必须返回一个,Observable<boolean>因为我必须在其他一些函数中使用它。
Aakash Thakur

您的getData()函数返回什么?
Aravind

的getData()返回[object Object]{id: "1234", isAdmin: false, userName: "Lama", newid: Array[1]}
Aakash塔库尔

对不起兄弟。我不是。
Aakash Thakur

我无法复制或显示您的屏幕,因为它不是家庭项目,它是机密信息,而这只是我遇到问题的一部分。
Aakash Thakur

5

我忘了归还另一个可观察到的 pipe(switchMap(

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

我没有正确模拟switchMap在单元测试中返回的observable具有相同的结果。
凯文·比尔

2

可以由,RxJS中的流逗号()触发pipe(...)

编译最后不会引起这个多余的逗号:

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

它变成了一个“不可见”的undefined运算符,将整个管道拧紧,并导致非常混乱的错误消息-在这种情况下,这与我的实际逻辑无关。


2

由于导入内部版本“ takeUntil”而不是运算符,导致了相同的问题

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

import { takeUntil } from 'rxjs/operators';

其他运营商也会发生这种情况


1

尝试使用JSON Web令牌对用户进行身份验证时,我一直遇到此问题。就我而言,它与身份验证拦截器有关。

发送验证用户身份的请求无需提供令牌,因为它尚不存在。

检查您的拦截器是否包含以下内容:

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

并且您提供{'No-Auth':'True'}给标题的请求是这样的:

  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

任何遇到此问题的人的提示。当aswitchMap没有收到可观察到的返回值(例如null)时,可能会发生这种情况。只需添加一个默认情况,所以它总是返回一个可观察的。

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

0

我写这篇文章是因为我到达这里是为了寻找相同的错误,这对将来的某个人可能很有用。

我尝试从其构造函数初始化服务变量并通过http.get和.subscribe()调用远程API时遇到相同的错误

经过多次测试,但不了解问题出在哪里,我终于明白了:我的应用程序具有身份验证和HttpInterceptor,并且我尝试使用http.get(...)初始化不带'No-Auth'调用公共API方法的服务'标头。我在这里添加了它们,问题为我解决了:

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

真是头疼:(



0

当我使用拦截器时,我发生了此错误,您必须在拦截器中执行此操作

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

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

        }

0

这个错误发生在我@angular 7

您提供了一个无效的对象,该对象应有一个流。您可以提供一个Observable,Promise,Array或Iterable。

该错误实际上是不言自明的,它表示somewhere在可见的情况下我传递了无效的对象。就我而言,有很多API调用,但是所有调用均由于服务器配置错误而失败。我尝试使用mapswitchMap或其他rxjs运算符,但是这些运算符正在获取未定义的对象。

因此,请仔细检查您的rxjs运算符输入。


0

当我在switchMap内调用方法时,我也面临着相同的问题,显然我发现,如果我们在switchMap内使用方法,它必须返回observable。

我使用管道返回可观察到的值,并使用映射在管道内部执行针对api调用的操作,这是我在方法内部进行的,而不是订阅该方法。


0

当项目之间存在不同的RxJS版本时,就会遇到此错误。RxJS的内部检查失败,因为有几种不同的检查方法Symbol_observable。最终,此函数一旦从类似的展平运算符调用就抛出switchMap

尝试在某些入口点导入符号可观察的符号。

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

0

我不确定这是否会对任何人有帮助,但是在我的情况下,我正在使用的链条更distinctUntilChanged深处,并且函数内的异常显示了此错误消息。


0

当您向期望Observable的操作员提供undefined时,您也会收到以下错误消息。takeUntil

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


-1

在进行单元测试并嘲笑我的服务后抛出可观察到的异常时,我得到了完全相同的错误消息。

我通过在内部传递确切的函数和格式来解决它Observable.throw

调用服务并subscribe获取数据的实际代码。注意catch处理400错误。

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

服务中的代码

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

单元测试

我已经模拟了SomeService并返回了可观察的数据及其良好的数据,因为它内部具有所有必需的方法。

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

上面的代码不错,但是当我试图通过传递来测试捕获/错误条件时,Observable.throw({})却向我显示错误,因为它期望Response从服务中返回类型。

所以下面的服务模拟返回给了我这个错误。

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

因此,我通过在返回对象中复制确切的预期函数而不是传递Response类型值来更正了它。

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

-2

关于“您在预期流中提供了一个无效的对象。您可以提供一个Observable,Promise,Array或Iterable”错误。

如果您(在下面)某个模块/功能/任何东西(实际使用它)import { Observable } from 'rxjs' 之后,可能会发生这种情况。

解决方案:将此导入移动到该模块的导入上方

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.