J. Adam Connor
J. Adam Connor

Reputation: 1734

No View Change After Firebase Node Deletion

Update: The following question relates to combineLatest not emitting anything when an empty array is passed to it. This may not be your problem specifically, but if your view isn't updating after removing or deleting a Firebase node, check your specific operators' handling of empty arrays. As described in the solution, some like combineLatest emit nothing when they receive empty arrays resulting in no change in the view.

Take the following example:

doSomething(): Observable<any> {
    let results = this.af.database.list(`path/to/something`)
    .switchMap(data => {
        let joinedObservables: any[] = [];
        data.forEach(item => {
            joinedObservables.push(this.af.database
                .object(`path/to/something/else`)
                .do(this => {
                    item.value = this.value;
                })
            )               
        })
        return Observable.combineLatest(joinedObservables, () => data)
    })
    return results
}

...and compare to this example:

doSomething(): Observable<any> {
    let results = this.af.database.list(`path/to/something`)
    .map(data => data.filter(data.poperty === predicate))
    return results
}

or an even simpler example:

doSomething(): Observable<any> {
    let results = this.af.database.list(`path/to/something`)
    return results
}

In the case of the first example, if you are rendering an item in your view, such as {{data.property}} and delete the entire data node from Firebase, the item rendered in the view will persist in the view. In other words, it will remain there until the page is reloaded.

In the final two examples the item will cease to be rendered the moment the Firebase object it is observing is deleted.

Why?

Upvotes: 1

Views: 79

Answers (1)

cartant
cartant

Reputation: 58410

In the first example, when you delete the data from the database, the list will emit an empty array. When that's received by the switchMap operation an empty array will be passed to combineLatest.

From memory, when combineLatest is passed an empty array, it emits nothing. With nothing emitted, the view sees no change, so previously rendered data persists.

If you were to check the length of the received array and emit an empty array if one is received, you should see the view updated.

By checking the length, I mean doing something like this:

return joinedObservables.length ?
  Observable.combineLatest(joinedObservables, () => data) :
  Observable.of([]);

Upvotes: 2

Related Questions