Reputation: 1483
What is the correct way to transform a object from a firebase list observable?
The following code has some side effects and create duplicated results in my templates. The first time it loads correctly but after visiting the page a second time, duplicated results are showing up.
loadAccountUsers() {
return this.af.database.list(`accounts/${this.authService.accountUID}/accountUsers`)
.flatMap(list => list)
.map((data: any) => {
let role: string = (data.accountLevel === 10 ? 'Administrator' : 'User');
return {
firstName: data.firstName,
lastName: data.lastName,
emailAddress: data.emailAddress,
role: role
};
})
.scan((arr, val) => arr.concat([val]), [])
}
When I don't transform the objects everything is fine
loadAccountUsers() {
return this.af.database.list(`accounts/${this.authService.accountUID}/accountUsers`)
}
Upvotes: 2
Views: 586
Reputation: 58410
flatMap
emits each element of the list into the observable stream. When the database changes and another list is emitted, its elements are emitted, too. However, the scan
operation is combining the emitted elements into a single array - hence the duplicates.
You could instead use the RxJS map
operator and the Array.prototype.map
method to solve the problem:
loadAccountUsers() {
return this.af.database.list(`accounts/${this.authService.accountUID}/accountUsers`)
.map((list) => list.map((data) => {
let role: string = (data.accountLevel === 10 ? 'Administrator' : 'User');
return {
firstName: data.firstName,
lastName: data.lastName,
emailAddress: data.emailAddress,
role: role
};
}));
}
Upvotes: 3