简体   繁体   English

AngularFire2 firestore在doc valueChanges上取(1)

[英]AngularFire2 firestore take(1) on doc valueChanges

Using AngularFire2 I try to get data from a single Firestore document. 使用AngularFire2我尝试从单个Firestore文档中获取数据。 What works is : 有效的是

this.addressRef = afs.doc<Address>('addresses/key')
this.addressRef.valueChanges().subscribe(val => {......}

I want to run the subscription code just once. 我想只运行一次订阅代码。 Normally I use take(1) to achieve this (works with the Firebase DB). 通常我使用take(1)来实现这一点(与Firebase DB一起使用)。 But this code : 但是这段代码

this.addressRef.valueChanges().take(1).subscribe(val => {......}

gives error : TypeError: this.addressRef.valueChanges(...).take is not a function. 给出错误 :TypeError:this.addressRef.valueChanges(...)。take不是函数。

VS Code is listing the take action. VS Code列出了采取行动。 Is this a bug in AngularFire2, am I doing this wrong or is there an other (better) way to stop the subscription after the data is fetched? 这是AngularFire2中的一个错误,我做错了还是有其他(更好的)方法在获取数据后停止订阅? I also tried topromise but this also failed. 我也尝试过topromise,但这也失败了。

update 更新

Because this answer has received a lot of attention, I have provided an updated answer. 因为这个答案得到了很多关注,所以我提供了一个更新的答案。 You should, in general, try to think reactively when programming with observables. 一般来说,在使用observable进行编程时,您应该尝试反应性思考。 There are some great tutorials, but this one is good. 有一些很棒的教程,但这个很好。

New solution 新解决方案

user$ = this.afDs.doc<User>('users/NaGjauNy3vYOzp759xsc')
  .valueChanges().pipe(
    take(1) // Here you can limit to only emit once, using the take operator
  )

And in your template, you subscribe to your observable. 在您的模板中,您订阅了您的observable。

{{(user$ | async).name}}

Context 上下文

This way of solving the problem has multiple benefits: 这种解决问题的方法有很多好处:

  • If you wan't to transform data, you just throw in a map operator 如果你不想转换数据,你只需要输入一个地图运算符
  • You can filter events with the rxjs filter operator 您可以使用rxjs过滤器运算符过滤事件
  • Create other streams, based on the user$ stream 根据用户$ stream创建其他流
  • easy debugging, because other developers can see the flow of data in your app in a more transparent way 易于调试,因为其他开发人员可以以更透明的方式查看应用程序中的数据流

For example (creating another stream, that only emits if the user is admin, and creates a new title): 例如(创建另一个流,只有在用户是管理员时才会发出,并创建一个新标题):

adminTitle$ = this.user$.pipe(
  filter(user => user.title === 'admin'),
  map(user => `${user.name} (admin)`)
)

Old answer 老答案

You can achieve this by doing the following: 您可以通过执行以下操作来实现此目的:

this.userDoc = afDs.doc<User>('users/NaGjauNy3vYOzp759xsc');
this.userDoc.valueChanges()
  .pipe(take(1))
  .subscribe(v => {
    this.user = v;
  });

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM