我的数据库中有两个节点:
users: {user1: {uid: 'user1', name: "John"}, user2: {uid: 'user2', name: "Mario"}}
homework: {user1: {homeworkAnswer: "Sample answer"}}
某些用户可能有功课,也可能没有功课。
我想通过一次调用就获得所有用户的列表以及每个用户的作业数据,然后进行订阅。实现这一目标的最佳方法是什么?
以下是上面示例中获得的列表的外观:
[{uid: 'user1', name: "John", homework: {homeworkAnswer: "Sample answer"}}, {uid: 'user2', name: "Mario"}]
这是我对users
和homework
的两个观察值:
let usersObservable = this.af.getObservable(`users/`);
let hwObservable = this.af.getObservable(`homework/`);
答案 0 :(得分:7)
基本上,您需要做两件事,但可能需要考虑一些细节。
使用forkJoin
可以轻松实现第一步。在forkJoin
中,您可以传入多个可观察对象,并且所有可观察对象完成后它将发出一个值。 重要:forkJoin
仅在完成后发出。如果您的数据来自商店或主题,则可能必须添加take(1)运算符,这样才能真正完成。
转换部分也应该很容易。我假设您要拥有用户对象中存在的所有用户,因此我们可以使用Object.keys
遍历现有用户键,然后使用map
来转换数据。
// Imports:
import { forkJoin } from 'rxjs';
import { take } from 'rxjs/operators';
// Step 1: Use fork join to get the result from both observables
forkJoin(
// pipe(take(1)) is only needed if the observables don't complete.
usersObservable.pipe(take(1)),
hwObservable.pipe(take(1))
)
// Step 2: Transform the data.
// We now need to map our both results. We want to return all
// users and add the homework if available. So we can user
// Object.keys to iterate over the existing user keys in your object.
.pipe(map(([users, homeworkMap]) => Object.keys(users)
// Now we can map the keys to the actual user objects
// and merge them with the homework
.map(userKey => {
const user = users[userKey];
const homework = homeworkMap[userKey];
return {
...user,
homework
};
})
))
.subscribe(users => console.log('Users: ', users));