New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Router - Clarify params subscription behavior when deactivating a route #16261
Comments
@robwormald Can you comment on how you think this should work? |
@mhevery @robwormald ping |
Plunkr https://plnkr.co/edit/ftZj8PPYV5lovmgpRXAT?p=preview Seems not to work like documented in 2.0.0, 4.0.0 and 4.2.0. All subscriptions remain. |
My understanding of this is that the source params/data/etc observables are garbage collected when the component and its injector with the Can someone confirm my assumptions? |
@sod @NetanelBasal Looking at that plnkr, it looks like only one message is being logged when switching between the XComponent and YComponent. This is with |
Yes, there is a problem, when you unsubscribe from the Observable the handler should NOT run. |
I just stumbled upon a slightly different problem, kind of opposite. I am seeing very strange routable component destroy/re-create if I don't include the |
@bennadel are you saying that the component is being destroyed, but then recreated when the params are changed? But it only occurs when you don't include the delay? |
@richarddavenport yes, that is correct. As far as I have isolated, it appears to be when I have a synchronous navigation away from the component from within the I hope to a working, isolated demo later today. |
@richarddavenport sorry, after further digging, it appears my issue has nothing to do with the I also created a new Ticket: #19999 ... it seems to only affect Chrome. |
Ok, after more noodling, I think my issue does have to do with |
The router is not auto unsubscribing for params or queryParams only when I have more than 1 instance of the same component being rendered in the page. |
Any update on this issue? I had to do a custom fix for this that adds some overhead but got the job done.... check the stack overflow link, I leave it here for anyone who needs a quick efficient fix for this: https://stackoverflow.com/questions/49159416/url-change-not-firing-in-angular/49159722#49159722 |
I'm searching for a while for the best practices of unsubscribing from observables at Angular and I decided to share with you the result of my searches to review it if I miss something. I see that this issue is related and decided to comment here instead of creating a question issue. Some of the best practices regarding observables unsubscriptions inside Angular components: A quote from
And in responding to the following links:
I collected some of the best practices regarding observables unsubscriptions inside Angular components to share with you:
A nice final tip: If you don't know if an observable is being automatically unsubscribed/completed or not, add a |
@m0uneer I very much disagree with
While this is true from the perspective of resources it only tells half the story. Let's say we're talking about directly calling http from within a component, and the http response took longer than needed so the user closed the component. The The point being never say never, and consider the effects of the 'subscribe callback' being run after the component is destroyed on a case by case basis. It may be better to 'unsubscribe', or it may be better to run the logic with some additional |
@simeyla, thanks for giving the time to review my comment and regarding the |
I am not sure if this is related, but I've noticed that ngOnDestroy() is called after the nagivation events, which in my case means that anything subscribed to queryParams will be called when the page navigates. |
I just noticed this too. I built my subscriptions on the assumption that ngOnDestroy would be called before ActivatedRoute.params pushes out another change and now I'm having problems. |
Looks like the original issue here is still a problem. Here's a reproduction in StackBlitz, if you open up the console you will see if you switch between the login page and something else, you will see that subscriptions keep getting created, but the subscriptions are never completed or unsubscribed. However per the docs here it says:
however it seems that is not true based on the above tests. Can someone confirm that I'm doing the right thing here to test this? |
@hahn-kev I'm pretty sure there will be no memory leaks. That's because the entity, in this case a I've detailed here why memory leaks occur when using a Subject. From my perspective, the Subject holds that subscribe's callback(it holds all the subscribers in a list) and when you unsubscribe, that subscriber(which indirectly links to the callback) is removed from the list. But if the thing that holds everything is destroyed, then I think there will be no memory leaks. |
This appears to be working as intended and as @Andrei0872 noted, it isn't a memory leak. It doesn't appear that the documentation is necessarily misleading, it's just that
You can play around with these scenarios here:
So even if the I'm lowering the priority here since I believe this is working as intended but that the documentation can be clarified to recommend unsubscribing if you need/desire the subscriptions to |
angular#16261 (comment) A couple important things to note about the behavior: * The component is destroyed, meaning that all of its members will be destroyed as well, including any subscriptions to the route params * This _does not_ mean that any `finalize` operators or `complete` on the subscription is called. This only happens if the source completes or you unsubscribe from the subscription. The documentation doesn't state that the `Router` will do this, though I can still understand why the behavior is confusing. You can play around with these scenarios here: https://stackblitz.com/edit/rxjs-hmpizx * `complete` the source without unsubscribe: `next`, `complete` and `finalize` are all called, even when `complete` is called before the `next` from the `delay` * `unsubscribe` from subscription without `complete` on the source: `finalize` happens, but the `complete` of the subscription does not, and neither does `next` So even if the `Router` were to call `complete` on all of the `Observables` on an `ActivatedRoute`, you would see that any subscriptions with a `delay` operator would still get called. resolves angular#16261
#16261 (comment) A couple important things to note about the behavior: * The component is destroyed, meaning that all of its members will be destroyed as well, including any subscriptions to the route params * This _does not_ mean that any `finalize` operators or `complete` on the subscription is called. This only happens if the source completes or you unsubscribe from the subscription. The documentation doesn't state that the `Router` will do this, though I can still understand why the behavior is confusing. You can play around with these scenarios here: https://stackblitz.com/edit/rxjs-hmpizx * `complete` the source without unsubscribe: `next`, `complete` and `finalize` are all called, even when `complete` is called before the `next` from the `delay` * `unsubscribe` from subscription without `complete` on the source: `finalize` happens, but the `complete` of the subscription does not, and neither does `next` So even if the `Router` were to call `complete` on all of the `Observables` on an `ActivatedRoute`, you would see that any subscriptions with a `delay` operator would still get called. resolves #16261 PR Close #42316
…42316) angular#16261 (comment) A couple important things to note about the behavior: * The component is destroyed, meaning that all of its members will be destroyed as well, including any subscriptions to the route params * This _does not_ mean that any `finalize` operators or `complete` on the subscription is called. This only happens if the source completes or you unsubscribe from the subscription. The documentation doesn't state that the `Router` will do this, though I can still understand why the behavior is confusing. You can play around with these scenarios here: https://stackblitz.com/edit/rxjs-hmpizx * `complete` the source without unsubscribe: `next`, `complete` and `finalize` are all called, even when `complete` is called before the `next` from the `delay` * `unsubscribe` from subscription without `complete` on the source: `finalize` happens, but the `complete` of the subscription does not, and neither does `next` So even if the `Router` were to call `complete` on all of the `Observables` on an `ActivatedRoute`, you would see that any subscriptions with a `delay` operator would still get called. resolves angular#16261 PR Close angular#42316
…42316) angular#16261 (comment) A couple important things to note about the behavior: * The component is destroyed, meaning that all of its members will be destroyed as well, including any subscriptions to the route params * This _does not_ mean that any `finalize` operators or `complete` on the subscription is called. This only happens if the source completes or you unsubscribe from the subscription. The documentation doesn't state that the `Router` will do this, though I can still understand why the behavior is confusing. You can play around with these scenarios here: https://stackblitz.com/edit/rxjs-hmpizx * `complete` the source without unsubscribe: `next`, `complete` and `finalize` are all called, even when `complete` is called before the `next` from the `delay` * `unsubscribe` from subscription without `complete` on the source: `finalize` happens, but the `complete` of the subscription does not, and neither does `next` So even if the `Router` were to call `complete` on all of the `Observables` on an `ActivatedRoute`, you would see that any subscriptions with a `delay` operator would still get called. resolves angular#16261 PR Close angular#42316
This issue has been automatically locked due to inactivity. Read more about our automatic conversation locking policy. This action has been performed automatically by a bot. |
Current behavior
This is a quote from the official documentation -
The subscription is still active.
Expected behavior
Angular should unsubscribe from the params observable when the component destroyed. ( or change the documentation )
Minimal reproduction of the problem with instructions
You can test this behavior with the
delay
operator.When navigates to a different route the handler is still running.
You can verify this by calling explicitly to the
unsubscribe()
method.Now you will see that the handler is not running.
Angular version: 4.0.X
The text was updated successfully, but these errors were encountered: