Search code examples
angularobservable

Is there any destroy hook for pipes in angular2 (same as for components)?


After investigating for several days(!?!) for a huge memory leakage of my current Angular2 application, I came up with the new discovery:

Apparently, an async pipe, which was heavily used throughout the application, was subscribing for an observable, but was never released (unsubscribed) when component and pipes where cleaned-up.

It accumulated to a number of ~11,000 observers for a single observable with very few user actions (which eventually caused the app to crash).

I need to unsubscribe the observable, and in order to do that I need a hook for destruction, similar to ngOnDestroy, but for pipes.

Is there any such hook, or if not, how would you suggest to unsubscribe?


Solution

  • If you take a look at the async pipe code, you can see that they are using ngOnDestroy just like how would you do it in a directive.

    snippet from AsyncPipe code:

    @Pipe({name: 'async', pure: false})
    @Injectable()
    export class AsyncPipe implements OnDestroy {
      ...
    
      ngOnDestroy(): void {
        if (isPresent(this._subscription)) {
          this._dispose();
        }
      }
      ...
    }
    

    The key is using: pure:false,

    From OnDestroy

    To create a stateful Pipe, you should implement this interface and set the pure parameter to false in the PipeMetadata.

    A stateful pipe may produce different output, given the same input. It is likely that a stateful pipe may contain state that should be cleaned up when a binding is destroyed. For example, a subscription to a stream of data may need to be disposed, or an interval may need to be cleared.