Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/460.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何处理未定义的观察值_Javascript_Angular_Typescript_Google Cloud Firestore_Rxjs - Fatal编程技术网

Javascript 如何处理未定义的观察值

Javascript 如何处理未定义的观察值,javascript,angular,typescript,google-cloud-firestore,rxjs,Javascript,Angular,Typescript,Google Cloud Firestore,Rxjs,在我的角度服务中,我提供了一个名为usageDoc$的公共可观察对象 service.ts: usageDoc$: Observable<IUsage>; initializeUsageDoc() { //gets called in app.component.ts on app load ... //some async db querying this.usageDoc$ = this.firestore.getUsageDoc(user.uid); //

在我的角度服务中,我提供了一个名为
usageDoc$
的公共可观察对象

service.ts:

usageDoc$: Observable<IUsage>;

initializeUsageDoc() {
  //gets called in app.component.ts on app load
  ...
  //some async db querying

  this.usageDoc$ = this.firestore.getUsageDoc(user.uid);  //getUsageDoc(..) returns Observable<IUsage>
}
这会导致以下错误:
无法读取未定义的属性subscribe…
,因为组件init上尚未设置
usageDoc$
。目前,我正在使用一种变通方法,即在服务中创建第二个可观察的
usageDocReady$=新主题
,该主题在设置
usageDoc$
后立即发出

有没有更好的办法来解决这个问题?我是否可以用默认值初始化
usageDoc$


我知道如果我使用异步管道在模板中订阅,我不会有这个问题,但是我需要一个正常的变量来显示问题,因此使用
localDoc

我建议使用带有缓冲区1的
ReplaySubject
。这将确保未来的用户能够获得最后一次发射,同时避免任何未定义的错误

private usageDocSrc=新的ReplaySubject(1);
public usageDoc$=this.usageDocSrc.asObservable();
initializeUsageDoc(){
//在应用程序加载时在app.component.ts中调用
...
//一些异步数据库查询
this.firestore.getUsageDoc(user.uid).subscribe({
next:value=>this.usageDocSrc.next(值)
});
}
如果您不希望使用
ReplaySubject
,那么我不理解
可观察对象的必要性。您可以直接从
getUsageDoc()
函数返回可观察的

initializeUsageDoc():可观察{
//在应用程序加载时在app.component.ts中调用
...
//一些异步数据库查询
返回此.firestore.getUsageDoc(user.uid);
}

尽管这将调用
getUsageDoc()
之前的所有语句,用于订阅
initializeUsageDoc()

,但我建议使用带有缓冲区1的
ReplaySubject
。这将确保未来的用户能够获得最后一次发射,同时避免任何未定义的错误

private usageDocSrc=新的ReplaySubject(1);
public usageDoc$=this.usageDocSrc.asObservable();
initializeUsageDoc(){
//在应用程序加载时在app.component.ts中调用
...
//一些异步数据库查询
this.firestore.getUsageDoc(user.uid).subscribe({
next:value=>this.usageDocSrc.next(值)
});
}
如果您不希望使用
ReplaySubject
,那么我不理解
可观察对象的必要性。您可以直接从
getUsageDoc()
函数返回可观察的

initializeUsageDoc():可观察{
//在应用程序加载时在app.component.ts中调用
...
//一些异步数据库查询
返回此.firestore.getUsageDoc(user.uid);
}

尽管这将调用
getUsageDoc()之前的所有语句,用于
initializeUsageDoc()的每个订阅

拥有
usageDoc$
usageDocSrc
有什么意义?@BojanKogoj:这是一种习惯性的力量,它使用了类似于
主题
重播主题
的多播结构。有些人不喜欢使用它:
usageDoc$=newreplaysubject(1)
。另请参阅。如果您试图阻止任何人从外部服务发送nexting,那么Ok是有意义的。在这种情况下,也要将
usageDocSrc
私有化?@bojankogj:是的,这是惯例(或者至少过去是这样)。我已经更新了答案。拥有
usageDoc$
usageDocSrc
有什么意义?@BojanKogoj:这是一种习惯性的力量,使用像
主题
重播主题
这样的多播结构。有些人不喜欢使用它:
usageDoc$=newreplaysubject(1)
。另请参阅。如果您试图阻止任何人从外部服务发送nexting,那么Ok是有意义的。在这种情况下,也要将
usageDocSrc
私有化?@bojankogj:是的,这是惯例(或者至少过去是这样)。我已经更新了答案。
localDoc: any;

ngOnInit() {
  this.service.usageDoc$.subscribe(doc=>this.localDoc=doc);
}