I am investigating an issue which appears to be coming from the fact that the "unsubscribe" method of the "Subscription" class does not appear to be disposing of the resources quickly enough which creates a memory leak.
Here is my scenario:
I have 2 components - LandingPageComponent (LPC) and WebPlayerComponent (WPC). The LPC is the first page that the user sees when they access the site. On that page, they have a link which takes them to the second page or WPC (passing an argument, e.g. "Operator Benchmarking") The user goes back to the previous page by clicking the browser's back button. That triggers the WPC's ngOnDestroy method which disposes of subscribtions (see code below).
WebPlayerComponent
export class WebPlayerComponent implements OnInit, OnDestroy {
@Input() workbookId: string;
@Input() workbookPage: string | number;
private _workbooks: Workbook[];
private _filters: Filter[];
private _subscriptions: { [key: string]: Subscription } = {};
ngOnInit() {
this._subscriptions["combined"] = combineLatest(
this.workbookService.workbooks$,
this.filterService.filters$,
this.libraryService.userFolderInitialised$
).subscribe(([workbooks, filters, userFolderInitialised]) => {
this._workbooks = workbooks;
this._filters = filters;
this._subscriptions["webPlayerServiceSubscription"] = this.webPlayerService.openWorkbook(workbook.libraryPath, parameterString).subscribe(
(webPlayer) => {
console.log("_subscriptions before 'openWorkbook call'");
Object.keys(this._subscriptions).map((key) => {
console.log(key);
});
console.log("Openning document page: " + this.workbookPage);
webPlayer.openDocument("spotfire-container", this.workbookPage);
});
});
}
ngOnDestroy() {
Object.keys(this._subscriptions).map((key) => {
this._subscriptions[key].unsubscribe();
console.log("---Unsubscribed " + key + "---");
});
}
}
The problem starts occuring if the user clicks the browser's Back button and clicks on the "Link" quickly enough (in my example that's anything less that 5seconds). The subscribtions that are supposed to be disposed are not and are still active. I am able to confirm that by looking at the console's output:
In the above image you can see that after clickon on the "Link" again from the LandingPageComponent we see 2 sets of calls (the green numbers (1) & (2)), we also see the "Opening document page:" 3 times
This is how the output should look like if I wait 5 seconds before I click the link again
I am not sure why my subscription resources are not being disposed of fast enough (at least that is what I think the problem here is).
Note: I am using RxJS 6.4.0 and Angular 8.1.3
You can use
switchMap
like:So you change your observable from
combineLatest
toopenWorkbook