简体   繁体   English

订阅被调用两次

[英]Subscribe is called twice

I'm trying to create a form to submit the details but when I subscribe the service, the subscription is done twice.我正在尝试创建一个表单来提交详细信息,但是当我订阅该服务时,订阅完成了两次。 First with null data and second with actual data.第一个是空数据,第二个是实际数据。

Component.ts组件.ts

addBook() {
    this.errorMessage = null;
    this.fireService.getBook(this.bookDetails.isbn).subscribe(data => {
      console.log('subscribe called');
      if (null != data) {
        this.dbox.open(DialogBoxComponent, {
          data: { title: 'Error', content: 'Book is already present in Library. Select Edit book to modify the details', button: false }
        });
        this.errorMessage = 'Book is already present in Library. Select Edit book to modify the details';
      } else {
        this.fireService.addBook(this.bookDetails);
        this.dbox.open(DialogBoxComponent, {
          data: { title: 'Success', content: 'Book has been Added to Database', button: false }
        });
        this.router.navigateByUrl('/add-book');
      }
    });
  }

Service.ts服务.ts

getBook(id) {
  console.log('called firebase get book');
  return this.db.doc(`/books/${id}`).valueChanges();
}

Below is the image from the console of chrome.下面是来自 chrome 控制台的图像。 This shows that the subscription is called twice but not the firebase service.这表明订阅被调用了两次,但不是 firebase 服务。

Chrome console logs: Image please click to view Chrome 控制台日志:图片请点击查看

chrome console logs chrome 控制台日志

called firebase get book
subscribe called
subscribe called

Please help请帮忙

It is because the observable returned by getBooks emits a new value when the Books collection changes.这是因为 getBooks 返回的 observable 在 Books 集合更改时会发出一个新值。 The first time there is no book with the same isbn so data is null.第一次没有具有相同 isbn 的书,因此数据为空。 Then you add one book and so the same observable fires again, this time with the book you just added然后你添加了一本书,所以同样的observable 再次触发,这次是你刚刚添加的书

If you only want to get data once, you can use take to only subscribe once.如果只想获取一次数据,可以使用 take 只订阅一次。

this.fireService.getBook(this.bookDetails.isbn).take(1).subscribe(data => {
  console.log('subscribe called');

like Chau Tran said, you can filter to get a valid response.就像 Chau Tran 所说的,您可以过滤以获得有效的响应。 If you haven't already, I'd add in a way to unsubscribe.如果您还没有,我会添加一种取消订阅的方式。 In the code below this.alive is a field that is true, and turned false in the OnDestory life hook.在下面的代码中this.alive是一个为真的字段,在 OnDestory 生活钩子中变成了假。

this.fireService.getBook(this.bookDetails.isbn)
.takeWhile(() => this.alive)
.filter(data => !!data)
.subscribe(...)

With in the function addBook you are calling the subscription.在函数addBook您正在调用订阅。 Each time you call the function addBook you are making a subscription call, Avoid using subscription in such functions.每次调用addBook函数addBook ,都是在进行订阅调用,避免在此类函数中使用订阅。 Make sure to subscribe only in onInit() , so that it checks whenever you make changes.确保仅在onInit()订阅,以便在您进行更改时进行检查。

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

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