【问题标题】:TypeError: You provided an invalid object where a stream was expected. You can provide an Observable, Promise, Array, or IterableTypeError:您在预期流的位置提供了无效对象。您可以提供 Observable、Promise、Array 或 Iterable
【发布时间】:2017-09-18 20:10:45
【问题描述】:

我正在尝试通过服务调用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:您在预期流的位置提供了无效对象。您可以提供 Observable、Promise、Array 或 Iterable

【问题讨论】:

  • 我收到了类似的问题:You provided 'undefined' where a stream was expected. You can provide an Observable, Promise, Array, or Iterable. 但它发生在我的服务器正在运行并且我在分支之间切换时。我需要做的就是重新启动我的服务器,然后它就消失了。
  • @AakashThakur 你的返回类型是Observable&lt;boolean&gt;。所以,你所有的 return 语句都应该返回一个 Observable 的布尔值。用of() 包裹return 语句。示例 1:return of(false) 示例 2:return of(e)

标签: angular typescript rxjs observable


【解决方案1】:

我在 NESTJS 中使用 RXJS 时遇到了类似的错误。

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

在我的例子中,我忘记在 switchMap 中返回一个 Observable。这导致在下一个 RXJS 操作符或客户端代码中没有收到 Observable。

一旦我在 switchMap 中返回了一个 Observable,错误就消失了。

【讨论】:

    【解决方案2】:

    就我而言,我错误地将 Action 导入了 combineEpic,而不是 Epic...

    验证 combine Epics 中的所有函数都是史诗函数

    【讨论】:

      【解决方案3】:

      当您向期望 Observable 的运算符提供 undefined 左右时,您也会收到以下错误消息,例如。 直到

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

      【讨论】:

        【解决方案4】:

        在我的情况下,错误仅发生在 e2e 测试期间。这是由我的 AuthenticationInterceptor 中的throwError 引起的。

        我从错误的来源导入它,因为我使用了 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,您的项目中可能同时有两个版本。
        • 我也遇到过类似的情况,我的拦截器只是在 if 中调用了next.handle(request)。所以拦截一个请求而不调用句柄之后会导致这个消息。
        • 我遇到了类似的问题,从 rxjs 的错误位置引入 interval。这是一个非常有帮助的答案,谢谢!
        • 就我而言,我只有retrun 而不是return throwError(error)。谢谢您的回答。
        【解决方案5】:

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

        【讨论】:

          【解决方案6】:

          当项目中有不同的 RxJS 版本时,我遇到了这个错误。 RxJS 中的内部检查失败,因为有几个不同的Symbol_observable。最终,this function 会从像 switchMap 这样的扁平化运算符调用一次。

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

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

          【讨论】:

            【解决方案7】:

            当我在 switchMap 中调用方法时,我也遇到了同样的问题,显然我发现如果我们在 switchMap 中使用方法,它必须返回 observable。

            我使用管道返回 observable 并映射以在管道内执行 api 调用操作,我在方法内部执行此操作,而不是订阅它。

            【讨论】:

              【解决方案8】:

              这个错误发生在我身上@angular 7

              您在预期流的位置提供了无效对象。您可以提供 Observable、Promise、Array 或 Iterable。

              该错误实际上是不言自明的,它在 observable 中显示 somewhere 我传递了无效对象。就我而言,有很多 API 调用,但由于服务器配置错误,所有调用都失败了。我尝试使用mapswitchMap 或其他 rxjs 运算符,但运算符得到未定义的对象。

              因此,请仔细检查您的 rxjs 操作员输入。

              【讨论】:

                【解决方案9】:

                当我使用拦截器时发生了这个错误 你必须在你的拦截器中这样做

                return next.handle(request).map(event => {
                        if (event instanceof HttpResponse) {
                
                        }
                        return event;
                    },
                      catchError((error: HttpErrorResponse) => {
                        if (error.status === 401 || error.status === 400) {
                          // some logic
                
                        }
                

                【讨论】:

                  【解决方案10】:

                  给遇到这种情况的人的提示。当switchMap 没有收到可观察的返回值(如null)时,可能会发生这种情况。只需添加一个默认情况,所以它总是返回一个 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;
                          })
                  

                  【讨论】:

                    【解决方案11】:

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

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

                    import { takeUntil } from 'rxjs/operators';
                    

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

                    【讨论】:

                      【解决方案12】:

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

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

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

                      【讨论】:

                        【解决方案13】:

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

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

                        【讨论】:

                          【解决方案14】:

                          我忘记返回 pipe(switchMap( 中的另一个 observable

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

                          【讨论】:

                          • 在我的单元测试中,我没有正确模拟 switchMap 中返回的 observable,结果相同。
                          【解决方案15】:

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

                          【讨论】:

                            【解决方案16】:

                            我写这个是因为我来到这里是为了寻找同样的错误,这可能对将来的人有用。

                            我在尝试通过 http.get 和 .subscribe()

                            从构造函数调用远程 API 时尝试初始化服务变量时遇到同样的错误

                            在不了解问题所在的情况下进行了多次测试,我终于明白了: 我的应用程序具有身份验证和 HttpInterceptor,我试图使用 http.get(...) 来初始化调用公共 API 方法的服务,而没有 'No -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】:

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

                              编译不会在末尾捕获这个额外的逗号:

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

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

                              【讨论】:

                                【解决方案18】:

                                我在尝试使用 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});
                                  }
                                

                                【讨论】:

                                  【解决方案19】:

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

                                  我通过在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
                                  

                                  【讨论】:

                                    【解决方案20】:

                                    您将返回一个 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&lt;boolean&gt;,因为我必须在其他一些函数中使用它。
                                    • 你的 getData() 函数返回什么?
                                    • getData() 返回[object Object]{id: "1234", isAdmin: false, userName: "Lama", newid: Array[1]}
                                    • 对不起兄弟。我不是。
                                    • 我将无法复制或显示我的屏幕,因为它不是家庭项目,它是机密的,这只是我遇到问题的一部分。
                                    【解决方案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';
                                    

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

                                    【讨论】:

                                    • 但我现在收到此错误:Error: Uncaught (in promise): [object ProgressEvent]
                                    • 您可以尝试将Observable.throw 行更改为Observable.of(并包含导入)。这将导致您的 observable 发出错误,但不会将其视为失败。 (基本上我们有点/但不是完全接受错误)。看看这是否从控制台中删除了错误。如果是,那么它指向 getData() 方法失败
                                    猜你喜欢
                                    • 1970-01-01
                                    • 1970-01-01
                                    • 2021-12-10
                                    • 2018-09-07
                                    • 2023-03-13
                                    • 2020-03-26
                                    • 1970-01-01
                                    • 1970-01-01
                                    • 1970-01-01
                                    相关资源
                                    最近更新 更多