1

Using rxjs@5, we implemented a convenient DisposeBag class to gather Subscriptions and make it easier to unsubscribe when destroying an Angular component.

import { Subscription } from "rxjs/Subscription";

export class DisposeBag {
    private _subscription: Subscription[] = [];

    insert(subscription: Subscription): void {
        this._subscription.push(subscription);
    }

    dispose() {
        this._subscription.forEach(subscription => {
            subscription.unsubscribe();
        });
        this._subscription = [];
    }
}

export function disposedBy(this: Subscription, bag: DisposeBag): void {
    bag.insert(this);
}

Subscription.prototype.disposedBy = disposedBy;

declare module "rxjs/Subscription" {
    interface Subscription {
        disposedBy: typeof disposedBy;
    }
}

Upgrading to rxjs@6 + rxjs-compat@6, we get the following compile errors:

(12) Property 'unsubscribe' does not exist on type 'Subscription'. (22) 'Subscription' only refers to a type, but is being used as a value here.

Switching the 1st import to

import { Subscription } from "rxjs";

solves both errors but introduces a (22) Property 'disposedBy' does not exist on type 'Subscription'. error.

How can we fix this?

Spiff
  • 2,266
  • 23
  • 36
  • 2
    Why not just use takeUntil with a Subject that emits on destroy? – Ingo Bürk Aug 09 '18 at 15:29
  • Seems like you also re-declare the module to modify the interface. After changing the import, did you change this re-declaration as well? – Vlad274 Aug 09 '18 at 15:30
  • @IngoBürk This class is used in 100+ sites at this point, so we want to keep it intact if possible. – Spiff Aug 09 '18 at 15:30
  • @Vlad274 Changing both the top import and the module declaration to "rxjs" gives the same two errors. – Spiff Aug 09 '18 at 15:32

1 Answers1

3

Thanks to this answer, I was able to fix it like this:

import { Subscription } from "rxjs";

export class DisposeBag {
    private _subscription: Subscription[] = [];

    insert(subscription: Subscription): void {
        this._subscription.push(subscription);
    }

    dispose() {
        this._subscription.forEach(subscription => {
            subscription.unsubscribe();
        });
        this._subscription = [];
    }
}

export function disposedBy(this: Subscription, bag: DisposeBag): void {
    bag.insert(this);
}

Subscription.prototype.disposedBy = disposedBy;

declare module "rxjs/internal/Subscription" {
    interface Subscription {
        disposedBy: typeof disposedBy;
    }
}
Spiff
  • 2,266
  • 23
  • 36