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

时间:2017-04-21 17:59:36

标签: angular typescript rxjs observable

我正在尝试从服务调用map但是收到错误。 看着subscribe is not defined in angular 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: You provided an invalid object where a stream was expected. You can provide an Observable, Promise, Array, or Iterable

20 个答案:

答案 0 :(得分:15)

在您的示例代码中,您的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';

修改 请注意,通过在catch处理程序中返回Observable.throw,您实际上不会捕获错误 - 它仍将显示在控制台上。

答案 1 :(得分:12)

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

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

错误:

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

正确:

import { throwError } from 'rjxs';

这是拦截器的完整代码:

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

答案 2 :(得分:7)

你正在返回一个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来检查您的病情

答案 3 :(得分:3)

如果你的函数希望返回一个布尔值,那就这样做:

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

答案 4 :(得分:2)

我遇到了同样的问题,原因是导入了内部版本的“ takeUntil”而不是运算符 更改

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

import { takeUntil } from 'rxjs/operators';

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

答案 5 :(得分:1)

尝试使用JSON Web Token对用户进行身份验证时,我一直面临这个问题。就我而言,它与身份验证拦截器有关。

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

检查你的拦截器是否包括:

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

答案 6 :(得分:1)

我忘记返回pipe(switchMap(中的其他可观察值

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

答案 7 :(得分:1)

任何遇到此问题的人的提示。当switchMap未收到可观察到的返回值(例如 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;
        })

答案 8 :(得分:0)

在我的情况下,我错误地将Action导入了我的CombineEpics中,而不是Epic中。

验证组合Epics中的所有功能都是史诗般的功能

答案 9 :(得分:0)

当您向期望( Observable )的操作员提供未定义的内容时,也会收到以下错误消息。 takeUntil

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

答案 10 :(得分:0)

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

答案 11 :(得分:0)

当项目之间存在不同的RxJS版本时,我会遇到此错误。 RxJS的内部检查失败,因为有几个不同的Symbol_observable。最终this function会从switchMap这样的扁平化运算符调用后抛出。

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

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

答案 12 :(得分:0)

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

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

答案 13 :(得分:0)

这个错误发生在我@angular 7

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

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

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

答案 14 :(得分: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

        }

答案 15 :(得分:0)

在我的Angular-5中,没有导入服务文件,而我正在从该文件访问方法并订阅数据。导入服务文件后,它工作正常。

答案 16 :(得分:0)

我写这封信是因为我到达这里是为了寻找相同的错误,这对以后的某个人可能很有用。

尝试从其构造函数初始化服务变量并通过http.get和 .subscribe()

调用远程API时,我遇到了相同的错误

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

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

多么头痛:(

答案 17 :(得分:0)

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

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

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

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

答案 18 :(得分:-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({}));

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

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

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

答案 19 :(得分:-2)

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

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

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