Angular TypeError:您提供了一个无效的对象,其中应该有一个流。您可以提供一个可观察的、承诺的、数组的或可观察的
我试图从一个服务呼叫Angular TypeError:您提供了一个无效的对象,其中应该有一个流。您可以提供一个可观察的、承诺的、数组的或可观察的,angular,typescript,rxjs,observable,Angular,Typescript,Rxjs,Observable,我试图从一个服务呼叫映射,但收到一个错误。 看了,上面说为了订阅,我们需要从运营商内部返回。我也有返回声明 这是我的密码: checkLogin():可观察{ 退回这个服务 .getData() .地图( (回应)=>{ 这个数据=响应; this.checkservice=true; 返回true; }, (错误)=>{ //调试器; this.router.navigate([“newpage”]); console.log(错误); 返回false; } ) .catch((e)=>{ 返
映射
,但收到一个错误。
看了,上面说为了订阅,我们需要从运营商内部返回。我也有返回声明
这是我的密码:
checkLogin():可观察{
退回这个服务
.getData()
.地图(
(回应)=>{
这个数据=响应;
this.checkservice=true;
返回true;
},
(错误)=>{
//调试器;
this.router.navigate([“newpage”]);
console.log(错误);
返回false;
}
)
.catch((e)=>{
返回e;
});
}
错误日志:
TypeError:您提供了一个无效的对象,其中应该有一个流。您可以提供一个可观察的、承诺的、数组的或可观察的
您返回的是一个可观察值,其中代码只返回一个布尔值。因此,您需要按如下方式使用
.map(response => <boolean>response.json())
这将使您的checkLogin()
函数返回类型为void
checkLogin():void{
this.service.getData()
.map(response => {
this.data = response;
this.checkservice=true;
}).subscribe(data=>{ });
您可以使用
this.checkService
来检查您的情况在示例代码中,您的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处理程序中返回
Observable.throw
,您实际上不会捕获错误-它仍然会出现在控制台上。我在进行单元测试时收到了相同的错误消息,并在模拟我的服务后引发了Observable exception
我通过在Observable.throw中传递确切的函数和格式来解决这个问题
调用服务并订阅以获取数据的实际代码。请注意,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({})
来测试catch/error条件时,它向我显示了错误,因为它期望响应
从服务返回类型
所以下面的服务模拟返回给了我这个错误
someServiceApi.getData
.and.returnValue(Observable.throw(new Response({status: 400, body: [], message: 'not found error'})));
因此,我通过在返回对象中复制准确的预期函数,而不是传递响应
类型值来纠正它
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
如果函数希望返回布尔值,请执行以下操作:
进口:
import{of,obobalable}from'rxjs';
从“rxjs/operators”导入{map,catchError};
然后
checkLogin():可观察{
返回此.service.getData()
.烟斗(
映射(响应=>{
这个数据=响应;
this.checkservice=true;
返回true;
}),
catchError(错误=>{
this.router.navigate(['newpage']);
console.log(错误);
归还(假);
})
)}
我在尝试使用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});
}
authenticateUser(用户):可观察{
const headers=新的HttpHeaders({'No-Auth':'True');
headers.append('Content-Type','application/json');
返回this.httpClient.post(`${this.apidentpoint}/auth/authenticate`,user,{headers:headers});
}
在我的例子中,错误只发生在e2e测试期间。这是由我的身份验证接收器中的投掷者引起的
我从错误的来源导入它,因为我使用了WebStorm的导入功能。我使用的是RXJS6.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);
})
);
}
}
从'@angular/core'导入{Injectable};
从'@angular/common/http'导入{HttpErrorResponse,HttpEvent,HttpHandler,HttpInterceptor,HttpRequest};
从“rxjs”导入{observatable,throwerr};
从“rxjs/operators”导入{catchError};
@可注射()
导出类AuthenticationInterceptor实现HttpInterceptor{
截取(req:HttpRequest,next:HttpHandler):可观察{
const reqWithCredentials=req.clone({withCredentials:true});
返回next.handle(reqWithCredentials)
.烟斗(
catchError(错误=>{
if(error.status==401 | | error.status==403){
//处理错误
}
返回投掷器(错误);
})
);
}
}
可以由RxJS管道(…)中的一个游离逗号(,
)触发。
编译程序不会在结尾捕获这个额外的逗号:
pipe(first(), map(result => ({ event: 'completed', result: result}),);
它变成了一个“不可见的”未定义的
操作符,这会把整个管道搞砸,并导致一条非常混乱的错误消息——在这种情况下,这与我的实际逻辑无关。我写这篇文章是因为我来到这里是为了寻找相同的错误,这对将来的人可能有用
我在试图通过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中,没有导入服务文件,我从中访问方法并订阅数据。导入服务文件后,它工作正常。我忘了返回其他观测值
pipe(first(), map(result => ({ event: 'completed', result: result}),);
getData() {
var reqHeader = new HttpHeaders({ 'Content-Type': 'application/x-www-urlencoded','No-Auth':'True' });
return this.http.get(environment.urlApi.Literales, { headers: reqHeader });
}
this.dataService.getPerson(personId).pipe(
switchMap(person => {
//this.dataService.getCompany(person.companyId); // return missing
return this.dataService.getCompany(person.companyId);
})
)
import { takeUntil } from 'rxjs/internal/operators/takeUntil';
import { takeUntil } from 'rxjs/operators';
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;
})
return next.handle(request).map(event => {
if (event instanceof HttpResponse) {
}
return event;
},
catchError((error: HttpErrorResponse) => {
if (error.status === 401 || error.status === 400) {
// some logic
}
// main index.ts
import 'symbol-observable';
TypeError: You provided an invalid object where a stream was expected. You can provide an Observable, Promise, Array, or Iterable