很抱歉,如果标题有点错误,但是我在此处发布此问题的原因是因为我有点儿不知所措,无法在网上找到我要找的东西。我也不太清楚我要寻找什么。
因此,我有一个角度应用程序,并且正在使用Firestore作为数据库。因此,我正在使用这段代码将我的收藏集添加到服务中:
this.userAsteroid$ = this.afs.collection<UserAsteroid>(this.collection).valueChanges();
然后我在服务中有一个函数返回this.userAsteroid $。然后,在我的组件的ngOnInit中,有以下内容:
this.userAsteroid$ = this.userAsteroidService.getAsteroids();
this.userAsteroid$.subscribe(asteroids => {
asteroids.forEach(document => {
if (document.asteroidId == this.id && document.userId == this.user.uid) {
this.hasAsteroid = true;
console.log("test: ", this.hasAsteroid);
}
console.log(document);
});
});
因此,基本上,我的组件是特定小行星的详细信息页面,并且当我的收藏集包含一个包含小行星ID和已登录用户的ID的文档时,我希望将bool hasAsteroid设置为true
这是组件的html
<div [hidden]="loading">
<div class="columns" *ngIf="!hasAsteroid && user">
<div class="column">
<button class="button is-primary is-outlined" type="button" (click)="addAsteroid(id)">Add to my asteroids</button>
</div>
</div>
现在,此方法有效,但仅当我重新加载页面时才有效,而当我导航至该页面时则无效。我怀疑这与以下事实有关:我使用的订阅函数不是异步的,因此有时在bool设为true之前会加载我的页面,然后使用该bool的* ngIf不会工作。
我尝试使用.pipe然后映射,就像处理从API接收的JSON数据一样,但是在这种情况下,它什么也没做。
在另一个组件中,我使用的是从服务到现在的相同功能,以获取一个用户已保存的所有小行星,如下所示:
getUserFeed() {
this.authService.userData$.subscribe(data => this.user = data);
this.userAsteroid$ = this.userAsteroidService.getAsteroids();
this.userAsteroid$.subscribe(asteroids => {
asteroids.forEach(document => {
if (document.userId == this.user.uid) {
console.log(document.asteroidId);
this.dataArray.push(document.asteroidId);
}
});
})}
如您所见,我会将用户保存的所有小行星ID推入数组,以便以后可以使用它们进行api调用。
我没有在这里写其余的代码,因为我知道由于该函数不异步而无法正常工作。
如果任何人都有解决方案,或者可以向我指出进行该工作所需的正确文档,我将非常感激。
编辑:
在课堂上进一步研究此问题之后,我解决了部分问题,并能够更准确地确定问题所在,但是问题仍然存在。在最初展示的两个函数中,我都有一部分使用此代码块
this.authService.userData$.subscribe(data => {
this.user = data;
this.userAsteroid$ = this.userAsteroidService.getAsteroids();
this.userAsteroid$.subscribe(asteroids => {
asteroids.forEach(document => {
if (document.asteroidId == this.id && document.userId == this.user.uid) {
this.hasAsteroid = true;
console.log("test: ", this.hasAsteroid);
}
console.log(document);
});
});
});
基本上,我正在订阅authSerivce来确定我的用户,在该订阅中,我订阅了我的Firestore服务,然后执行了一些工作。
当我最初加载组件时,所有这些都有效。但是,我在路由中使用参数来处理“标签”。我在ngOnit中订阅了这些参数,因此当我单击导航中的链接时,我的页面将使用正确的参数更新组件。然后,在此订阅中,我想起了我的功能。
但是,当我回忆起该函数时,它仍将订阅用户,仍将从Firestore获取可观察对象,但不会再次订阅该可观察对象。基本上,当我调用该函数时,从此行开始的所有内容都无法正常工作
this.userAsteroid$.subscribe(asteroids => {
有人知道为什么吗?
答案 0 :(得分:1)
如何将文档查找移到auth订阅中?
getUserFeed() {
this.authService.userData$.subscribe(data => {
this.user = data
this.userAsteroid$.subscribe(asteroids => {
asteroids.forEach(document => {
if (document.userId == this.user.uid) {
console.log(document.asteroidId);
this.dataArray.push(document.asteroidId);
}
});
})}
});
this.userAsteroid$ = this.userAsteroidService.getAsteroids();
}
通过这种方式,可以保证只有在userAsteroid$
可用后才能建立this.user
订阅。
如果您选择这条路线,则可能需要检测是否已经订阅this.userAsteriud$
,并在这种情况下跳过重新订阅。
答案 1 :(得分:1)
只有在获得用户ID后,才需要对小行星发起请求。因此,您的代码应位于用户数据的订阅结果中。
否则,这取决于您收到响应的顺序:如果您在之前获得小行星,则this.user
尚未设置。
您可以在每个事件处理程序中看到console.log
,这很明显。
因此,您的代码将变为:
getUserFeed() {
this.authService.userData$.subscribe(data => {
this.user = data;
this.userAsteroid$ = this.userAsteroidService.getAsteroids();
this.userAsteroid$.subscribe(asteroids => {
asteroids.forEach(document => {
if (document.userId == this.user.uid) {
console.log(document.asteroidId);
this.dataArray.push(document.asteroidId);
}
});
});});
}