You have misunderstood how Subscription
and add
work.
When you subscribe
to something, you get a Subscription
object, to which you can call unsubscribe()
. This is fine. However, you haven't assigned the value correctly. You assigned the Subscription
to const sub
, which you then pass in as the completion
block to add
.
Consider Subscription.add
like a finally
block of a try/catch
. No matter what the result of the Subscription
, when it is complete
, the block passed to add
will execute. Use this for any cleanup tasks.
subscriptions: Subscriptions[] = [];
ngOnDestroy() {
subscriptions.forEach((sub) => sub.unsubscribe());
}
deleteFile(id: any) {
const sub = this.fileCabinetService.deleteFile(id).subscribe(...);
this.subscriptions.push(sub);
sub.add(() => this.subscriptions.remove(sub));
}
To answer your question about when to unsubscribe
, it really depends on what deleteFile
does. If the deleteFile
method internally signals with a value (or a set of values) and then is completed, the subscription is terminated automatically. If it is not completed and left dangling, then your subscription will persist.
Consider the scenario of:
WallClock.subscribe((time) => console.log(time));
This Subscription
will never be terminated because time (presumably) will continue indefinitely. Instead, you will want to manually control when this is terminated. You can do this in a few ways:
/* Get the current time, but don't bother listening to updates. */
WallClock.pipe(take(1)).subscribe((time) => console.log(time));
/* Continually update with the current time as long as the component is on screen
— Requires setting `this.staySubscribed = false` when you're leaving */
WallClock.pipe(takeWhile(() => this.staySubscribed)).subscribe((time) => console.log(time));
/* Continually update until you remember to unsubscribe
— Requires remembering to unsubscribe and can get verbose with multiple subscriptions
- Call `this.subscription.unsubscribe()` later */
this.subscription = WallClock.subscribe((time) => console.log(time));
If your deleteFile
operates like this and continually reports values without a definite completion condition, you should make sure to terminate the subscription in some way. It is likely the case (based on the name of the function) that this is a self-terminating Subscription
that will not require anything on your part. If you want to be really safe, the pipe(take(1))
will ensure it for you.