[英]Angular: You provided an invalid object where a stream was expected. You can provide an Observable, Promise, Array, or Iterable
[英]TypeError: You provided an invalid object where a stream was expected. You can provide an Observable, Promise, Array, or Iterable
我正在尝试从服务调用进行map
,但出现错误。 看subscribe 是不是在 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;
});
}
错误日志:
类型错误:您提供了一个预期流的无效对象。 你可以提供一个 Observable、Promise、Array 或 Iterable
在我的情况下,错误仅在 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);
})
);
}
}
在您的示例代码中,您的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);
})
}
您还需要导入catch
和throw
运算符。
import 'rxjs/add/operator/catch';
import 'rxjs/add/observable/throw';
编辑:请注意,通过在 catch 处理程序中返回Observable.throw
,您实际上不会捕获错误 - 它仍然会出现在控制台上。
如果您的函数期望返回布尔值,请执行以下操作:
import { of, Observable } from 'rxjs';
import { map, catchError } from 'rxjs/operators';
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);
})
)}
您正在返回一个 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
来检查你的情况
我忘记返回pipe(switchMap(
的另一个可观察对象pipe(switchMap(
this.dataService.getPerson(personId).pipe(
switchMap(person => {
//this.dataService.getCompany(person.companyId); // return missing
return this.dataService.getCompany(person.companyId);
})
)
pipe(...)
的杂散逗号 ( ,
) 触发pipe(...)
编译不会在最后捕获这个额外的逗号:
pipe(first(), map(result => ({ event: 'completed', result: result}),);
它变成了一个“不可见”的undefined
运算符,它将整个管道拧紧,并导致非常混乱的错误消息 - 在这种情况下与我的实际逻辑无关。
我有同样的问题,因为导入了“takeUntil”的内部版本而不是操作符 Change
import { takeUntil } from 'rxjs/internal/operators/takeUntil';
到
import { takeUntil } from 'rxjs/operators';
这也发生在其他运营商身上
我在尝试使用 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});
}
给任何遇到这种情况的人的提示。 当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;
})
我写这篇文章是因为我来到这里寻找相同的错误,这可能对将来的某个人有用。
我在尝试从其构造函数初始化服务变量时遇到相同的错误,通过 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 });
}
好头疼:(
就我在 Angular-5 中的情况而言,没有导入服务文件,我正在访问该方法并订阅数据。导入服务文件后,它工作正常。
当我使用拦截器时,我发生了这个错误,您必须在拦截器中执行此操作
return next.handle(request).map(event => {
if (event instanceof HttpResponse) {
}
return event;
},
catchError((error: HttpErrorResponse) => {
if (error.status === 401 || error.status === 400) {
// some logic
}
这个错误发生在我身上@angular 7
您在需要流的地方提供了一个无效的对象。 您可以提供 Observable、Promise、Array 或 Iterable。
该错误实际上是不言自明的,它说在 observable 的somewhere
我传递了无效对象。 就我而言,有很多 API 调用,但由于服务器配置错误,所有调用都失败了。 我尝试使用map
、 switchMap
或其他 rxjs 运算符,但这些运算符正在获取未定义的对象。
因此,请仔细检查您的 rxjs 操作员输入。
当我在 switchMap 内部调用方法时,我也面临同样的问题,显然我发现如果我们在 switchMap 内部使用方法,它必须返回可观察的。
我使用管道返回 observable 并映射以在管道内执行操作以进行 api 调用,这是我在方法内部执行而不是订阅它。
当跨项目存在不同的 RxJS 版本时,我遇到了这个错误。 RxJS 中的内部检查失败,因为有几个不同的Symbol_observable
。 最终这个函数抛出一次从像switchMap
这样的扁平操作符switchMap
。
尝试在某个入口点导入符号可观察。
// main index.ts
import 'symbol-observable';
我不确定这是否会对任何人有所帮助,但在我的情况下,我使用了distinctUntilChanged
并且在函数内部出现了一个异常,并显示了此错误消息。
当您向需要 Observable的运算符提供 undefined 左右时,您也会收到以下错误消息,例如。 直到.
TypeError: You provided an invalid object where a stream was expected. You can provide an Observable, Promise, Array, or Iterable
就我而言,我错误地将 Action 导入到我的 combineEpics 中,而不是 Epic 中...
验证组合史诗中的所有函数都是史诗函数
我在 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,错误就消失了。
在进行单元测试并在模拟我的服务后抛出可观察到的异常时,我有相同的错误消息。
我通过在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
关于“您在需要流的地方提供了无效对象。您可以提供 Observable、Promise、Array 或 Iterable”错误。
如果您在(下面)某个模块/函数/任何实际使用它的模块/函数/任何东西之后import { Observable } from 'rxjs'
就会发生这种情况。
解决方案:将此导入移动到该模块的导入上方。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.