Reputation: 2021
We have an rxjs subscription that's failing to close. I'm wondering if this is a bug in the rxjs library or if we're doing something wrong.
Our code looks like this:
private loadGroups(): void {
if (this.groupOptionsSubscription?.closed === false){
this.groupOptionsSubscription.unsubscribe();
}
this.groupOptionsSubscription =
this.lookupService
.getGroupLookups(null, this.filter.companyId)
.pipe(debounceTime(environment.filterDelay))
.subscribe(
(groups) => {
this.groupOptions$.next(groups);
setTimeout(() => {
console.log(this.groupOptionsSubscription.closed);
}, 5000);
});
}
In this method, there is a subscription called groupOptionsSubscription
. It first checks if it's not closed (or exists). If it is not closed (and it exists), we unsubscribe (which closes it immediately). Then we assign it to a new subscription that comes from this.lookupService.getGroupLookups()
. When the observable fires, the subscribe callback runs. Once the callback is finished, the subscription should close (right?). Most of the time it does, but sometimes it doesn't. I can test this by console logging the closed state of the subscription in a 5 second timeout. About 1 in 5 times, it shows that the subscription is not closed.
This method can be called more than once before the previous observables fire. For example, it can be called 3 times, and only after the third time will the subscription callback run, with the previous two network requests being canceled and the previous two subscriptions being (I guess) disposed. In other words, only the last one completes. I have verified that it is this last one which also (sometimes) fails to close.
Does anyone know why this might be happening? Is this a known bug with the rxjs library? Or does it have something to do with the way we're handling subscriptions? Thanks.
Upvotes: 2
Views: 958
Reputation: 20619
Maybe there's something in getGroupLookups that's causing the observable to stay open? You could add a take(1) to the pipe, but here's the thing, rxjs already has mechanisms to manage subscriptions. So instead of trying to keep track if a subscription is open or closed, just use what rxjs already has.
readonly loadGroupsSubject = new Subject();
readonly groupOptions$ = this.loadGroupsSubject.pipe(
switchMap(() => this.getGroupLookups(null, this.filter.companyId)),
debounceTime(environment.filterDelay)
);
Upvotes: 1