Frank Spin
Frank Spin

Reputation: 1483

Correct way to transform Object from Firebase list?

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

Answers (1)

cartant
cartant

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

Related Questions