我编写了一个查询,如下所示:
getPaymentByBookingId(id: string): Observable<Payment> {
return this.afs.collection<Payment>('payments', ref => ref.where('bookingId', '==', id).limit(1))
.valueChanges()
.pipe(
flatMap(array => from(array)),
first()
);
}
Payment
对象具有对Booking
id的唯一引用。我想找到给定ID的付款。
这似乎是解决该查询的一种复杂方法。
是否有更简单的方法来执行此操作-包括是否存在使此操作困难的代码气味?
答案 0 :(得分:0)
您可以仅使用Javascript本地数组API .find()
来完成此操作,这样可以节省几行代码:
getPaymentByBookingId(id: string): Observable<Payment> {
return this.afs.collection<Payment>('payments')
.valueChanges()
.pipe(
map(allPayments=>allPayments.find(payment=>payment.bookingId === id))
);
}
或者您可以使用.first()
运算符并提供其第一个满足条件:
getPaymentByBookingId(id: string): Observable<Payment> {
return this.afs.collection<Payment>('payments')
.valueChanges()
.pipe(
flatMap(array => from(array)),
first(eachPayment => eachPayment.bookingId === id)
);
}
请注意,幕后过滤的工作方式存在根本差异。我个人更喜欢Javascript的本机功能,因为我觉得使用from(array)
转换可观察对象只是一种多余的操作,以至于它可以逐一发出数组序列。
还要注意,通过执行ref => ref.where('bookingId', '==', id)
,过滤实际上发生在查询级别(即不在客户端)。如果您确信检索到的payments
的数量不会很大,那么可以让客户端进行过滤;否则将处理部分卸载到服务器总是更好。
答案 1 :(得分:0)
简单一点:
getPaymentByBookingId(id: string): Observable<Payment> {
return this.afs.collection<Payment>('payments', ref => ref.where('bookingId', '==', id).limit(1))
.valueChanges()
.pipe(
map(array => array[0]),
);
}
如果未找到付款,它将返回undefined
。