我对Observable
参数有疑问,在我的情况下,我有一个具有函数consult()
的consultService和参数响应。在使用参数响应之前调用sendConsultRequest()
函数。 sendConsultRequest工作正常,因为我可以在页面中看到结果,但是当我想通过使用参数响应导出内容时,我遇到了问题:
错误类型错误:无法读取属性' dataList'未定义的
在我的操作中,响应参数已在导出操作之前初始化,因为consultPage运行良好。 这是服务代码,你能告诉我它为什么不起作用吗?
@Injectable()
export class ConsultService {
private url = 'api/consultApplication';
response: Application;
sendConsultRequest(id: string) {
console.log('sendConsultRequest');
this.http.get<Application[]>(this.url)
.subscribe(response => {
response.map(res => {
this.response = res;
this.updateApplication(res);
}),
pipe(catchError(this.handleError('sendConsultRequest', [])));
});
}
这是导出页面ts:
ngOnInit() {
console.log('ExportComponent init');
console.log(this.consultService.response);
this.application = this.consultService.response;
this.appID= this.consultService.response.dataList.find(pair => 'PROCEDURE' === pair.field)
? this.consultService.response.dataList.find(pair => 'PROCEDURE' === pair.field).value : null;
}
谢谢。
答案 0 :(得分:2)
这不是它的工作方式。
以下是它的工作原理。
@Injectable()
export class ConsultService {
private url = 'api/consultApplication';
response: Application;
sendConsultRequest() {
console.log('sendConsultRequest');
return this.http.get<Application[]>(this.url)
}
在您的组件中
ngOnInit() {
console.log('ExportComponent init');
console.log(this.consultService.response);
this.consultService.sendConsultRequest().subscribe(
response => {
response.map(res => {
this.consultService.updateApplication(res);
this.appID = response.dataList.find(pair => 'PROCEDURE' === pair.field);
});
}, error => this.consultService.handleError('sendConsultRequest', [])
);
}
你这样做的方式,你从不打电话给你的服务(或者你没有发布代码)。并且由于您的服务进行异步调用,并且您希望等待它,您应该让组件等待它,而不是您的服务。
您采用这种方式,您的组件不会等待您的服务结束通话。它只是取一个蓝色的值,这个值可能等于null或undefined。
答案 1 :(得分:2)
每当出现Cannot read property 'foo' of undefined
错误时,这意味着您尝试从中读取数据的对象从未分配过值。
在JavaScript中,如果您没有设置某些内容,它将始终默认为undefined
。
let foo; // foo is undefined
此外,如果您期望函数中的参数但该参数从未赋值,那么它也将是未定义的。
function foo(arg) {
console.log(foo);
}
foo(); // the console logs 'undefined'
因此,当您遇到这类错误时,这是一个很好的经验法则,这意味着变量从未在代码中分配过值,您应该查看您正在分配的思考的位置它是一个值,并重新读取代码,以确保它实际上是你想要它的工作。
这一行:
this.appID= this.consultService.response.dataList.find(pair => 'PROCEDURE' === pair.field)
? this.consultService.response.dataList.find(pair => 'PROCEDURE' === pair.field).value : null;
在这种情况下不起作用,因为this.consultService.response
未定义。您只能在为this.consultService.response
分配值后调用该逻辑。
未定义的原因是您进行异步HTTP调用,然后尝试立即访问该值。但HTTP调用尚未返回,因此您的值将不确定。
如果要从异步HTTP调用接收值,则应从服务返回observable,然后在组件中订阅它。
服务:
sendConsultRequest(id: string): Observable<any> {
return this.http.get<Application[]>(this.url).pipe(
tap(response => {
return response.map(res => {
this.response = res;
this.updateApplication(res);
})
),
catchError(this.handleError('sendConsultRequest', []))
);
}
现在在您的组件中:
ngOnInit() {
this.consuleService
.sendConsuleRequestId(id)
.subscribe(response => {
this.appID = response.dataList.find(pair => 'PROCEDURE' === pair.field) ? response.dataList.find(pair => 'PROCEDURE' === pair.field).value : null;
});
}
更新(显示ReplaySubject
示例) - 未经测试:
服务:
consultStream: ReplaySubject = new ReplaySubject();
consult$: Observable<Consult> = this.consultStream.asObservable();
constructor() {
this.sendConsultRequest(1);
}
sendConsultRequest(id: string): Observable<any> {
return this.http.get<Application[]>(this.url)
.subscribe((consult: Consult) => this.consultStream.next(consult));
}
组件:
ngOnInit() {
this.consult$
.subscribe((consult: Consult) => {
// ...
});
}