Issue
In an Angular app, I'm managing my subscriptions by pushing them all into an array, then looping through it and unsubscribing during ngOnDestroy
.
private subscriptions: Subscription[] = []
this.subscriptions.push(someObservable.subscribe(foo => bar))
My problem is that I haven't found a sufficiently clean way to handle the unsubscription. The ideal way would be a simple
ngOnDestroy () {
this.subscriptions.forEach(subscription => subscription.unsubscribe())
}
but this doesn't work. Notably, I'm still receiving Firebase permission errors after logging out (which doesn't happen with the "working" methods). Interestingly, the exact same method does work if I pull it out into a separate class:
export class Utils {
public static unsubscribeAll (subObject: {subscriptions: Subscription[]}) {
subObject.subscriptions.forEach(subscription => subscription.unsubscribe())
}
}
// ---------- back to the component
ngOnDestroy () {
Utils.unsubscribeAll({subscriptions: this.subscriptions}) // no Firebase errors
}
but I don't really like this solution, mostly because it only works if I wrap the array in an object so it passes as a reference. The other working method I found was to write it as a for loop:
ngOnDestroy () {
/* tslint:disable */
for (let i = 0; i < this.subscriptions.length; i++) {
this.subscriptions[i].unsubscribe()
}
/* tslint:enable */
}
but aside from the unnecessary length, it also makes TSLint complain because it thinks I should be using a for-of loop instead (which doesn't work) so I have to throw in the extra comments every time.
Currently I'm using the Utils option as the "best" solution, but I'm still not happy with it. Is there a cleaner way to do this that I'm missing?
Solution
Since nobody wants to post their answer as an answer, I guess I'll do it.
If you're only using the array to group them for mass unsubscribing, you can accomplish the same thing by merging them into an existing subscription. For my setup, just change the empty array to an empty subscription and change push
to add
:
private subscriptions = new Subscription()
this.subscriptions.add(someObservable.subscribe(foo => bar))
Then, when you want to unsubscribe from them all, just unsubscribe from the container subscription and it will handle everything.
ngOnDestroy () {
this.subscriptions.unsubscribe()
}
Note: you can also use takeUntil
on each individual subscription, but I feel like this method is simpler and makes more sense for what I'm doing.
Answered By - John Montgomery
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.