【问题标题】:mergeMap not returning data when inner observable is empty/ api returns no data当内部可观察对象为空/ api 不返回数据时,mergeMap 不返回数据
【发布时间】:2020-05-13 06:45:54
【问题描述】:

我正在尝试合并三个可观察对象,当内部可观察对象没有任何数据时,mergeMap 不会返回任何数据。即使内部可观察对象之一为空,我也希望能够继续该过程。我该如何处理这种情况?这是我的代码:

    ngOnInit() {
        this.accountStatusSub = this.accountService.accountNumberChange$.subscribe(
          accNumber => 
              {this.accountNumber = accNumber;


            var obs = this.accountService.getAccountDetails(this.accountNumber)
                  .pipe(mergeMap(accountData =>
                    this.accountService.getBill(accountData.account[0].accountNumber)
                      .pipe(mergeMap(billData =>
                        this.accountService.getPayment(accountData.account[0].accountNumber)
                          .pipe(map(paymentData => ({
                            address1: accountData.account[0].address1,
                            address2: accountData.account[0].address2,
                            city: accountData.account[0].city,
                            state: accountData.account[0].state,
                            zip: accountData.account[0].zip,
                            amountDue: billData.bill[0].amountDue,
                            dueDate: billData.bill[0].dueDate,
                            lastPaymentAmount: paymentData.payment[0].paymentAmount,
                            lastPaymentDate: paymentData.payment[0].paymentDate
                          })

                          ))
                      ))
                  ))


                obs.subscribe(combinedAccountData => {
                  console.log('MergeMap:', combinedAccountData)
                })

              })
          }

当 billData 或 paymentData 为空时,combinedAccountData 为空。有没有更好的方法来编写上面的代码?我是 Angular 和 rxjs 的新手。谢谢。

【问题讨论】:

  • 既然你可以从一开始就知道obs.是否为空,是否会有超时声明它为空?
  • 您能详细说明一下吗?我可以在代码中的哪个位置执行此操作?我是 Angular 新手,但仍在尝试弄清楚。
  • 所以你说一个 observable 可以是空的,但是你怎么知道它是空的并且不会比预期的时间长一点?它是否必须发射到一定的时间,否则它被认为是空的?另外,如果一个 obs 为空,“继续该过程”是什么意思?预期的行为是什么?
  • 它现在的工作方式是按照上面的代码,例如,如果 api 调用没有返回 paymentData 行,则没有为 accountData 或 billData 设置值。即使 paymentData 或 billData(getBill 或 getPayment)不返回任何行,我也希望能够检索其余字段(如 address1、账单数据等)的值。

标签: angular rxjs mergemap


【解决方案1】:

更新

理想的状态是通过

ngOnInit() {
  this.accountStatusSub = this.accountService.accountNumberChange$.pipe(
    tap(accNumber => console.log(accNumber)),
    mergeMap(accNumber => {
      this.accountNumber = accNumber;
      const getAccount = this.accountService.getAccountDetails(accNumber);
      const getBill = this.accountService.getBill(accNumber);
      const getPayment = this.accountService.getPayment(accNumber);
      return forkJoin(getAccount, getBill, getPayment);
    })
   ).subscribe();
}

原创

如果他们可以返回空数据,您可以返回一个空对象并传播它。取决于你想要得到的结构。

ngOnInit() {
    this.accountStatusSub = this.accountService.accountNumberChange$.pipe(
        switchMap(accNumber =>
            this.accountService.getAccountDetails(accNumber),
        ),
        switchMap(accountData => combineLatest([
            of(accountData),
            this.accountService.getBill(accountData.account[0].accountNumber),
            this.accountService.getPayment(accountData.account[0].accountNumber),
        ])),
        map(([accountData, billData, paymentData]) => ({
            address1: accountData.account[0].address1,
            address2: accountData.account[0].address2,
            city: accountData.account[0].city,
            state: accountData.account[0].state,
            zip: accountData.account[0].zip,
            billData,
            ...( billData?.bill && billData.bill[0] ? {
              amountDue: billData.bill[0].amountDue,
              dueDate: billData.bill[0].dueDate,
            } : {}),
            paymentData,
            ...( paymentData?.payment && paymentData.payment[0] ? {
              lastPaymentAmount: paymentData.payment[0].paymentAmount,
              lastPaymentDate: paymentData.payment[0].paymentDate
            } : {}),
        }))).subscribe(combinedAccountData => {
            console.log('MergeMap:', combinedAccountData)
        });
}

【讨论】:

  • 我认为 OP 将 empty observable 称为发出空数据的 observable,而不是根本不发出数据的 observable。
  • 真的吗?那听起来太容易了。只是你一个 if 或 '?.'
  • 是的,Andrei Gătej 是正确的。我尝试使用 iif 但不太确定如何以及在何处使用它。请帮忙。
  • 这样尝试:paymentData?.payment[0].paymentDate - ?. 会起作用吗?
  • @satanTime - 谢谢!下面的代码似乎也有效: ngOnInit() { this.accountStatusSub = this.accountService.accountNumberChange$.pipe( tap(accNumber => console.log(accNumber)), mergeMap(accNumber => { this.accountNumber = accNumber ; const getAccount = this.accountService.getAccountDetails(accNumber); const getBill = this.accountService.getBill(accNumber); const getPayment = this.accountService.getPayment(accNumber); return forkJoin(getAccount, getBill, getPayment); }) ) .subscribe(res => }) }
猜你喜欢
  • 2017-06-17
  • 2023-03-10
  • 1970-01-01
  • 2021-05-13
  • 2018-12-16
  • 1970-01-01
  • 2020-03-21
  • 1970-01-01
  • 2018-02-01
相关资源
最近更新 更多