Repository navigation
Closed
Labels
area: coreIssues related to the framework runtimeIssues related to the framework runtimefeatureLabel used to distinguish feature request from other issuesLabel used to distinguish feature request from other issuesfreq1: low
Description
[ ] bug report => search github for a similar issue or PR before submitting
[X ] feature request
[ ] support request => Please do not submit support request here, instead see https://github.com/angular/angular/blob/master/CONTRIBUTING.md#question
Current behavior
See example below:
@Injectable()
export class GlobalServiceProvidedInBootstrap {
public subscribe(f: Function);
public unsubscribe(f: Function);
}
export function callback() {
};
@Injectable()
export class ServiceProvidedInElement {
constructor(public service: GlobalServiceProvidedInBootstrap) {
service.subscribe(callback);
}
}
@Component({
selector: 'example-tag',
providers: [ServiceProvidedInElement]
})
export class ExampleTagComponent {
constructor(private s: ServiceProvidedInElement) {
}
public ngOnDestroy() {
this.s.service.unsubscribe(callback);
}
}
The problem I'm having in similar code is that the moment this component is destroyed, there is no way for me to unsubscribe ServiceProvidedInElement from GlobalServiceProvidedInBootstrap unless I use ngOnDestroy in the component.
Expected/desired behavior
The expected behavior is that when I declare my providers, I should be able to set a callback to destroy my service provided. So instead of using ngOnDestroy I could do it like this:
export SERVICE_PROVIDED_IN_ELEMENT_PROVIDERS = [
{
token: ServiceProvidedInElement,
useDestructor: function (element: ServiceProvidedInElement) {
element.service.unsubscribe(callback);
}
}
];
Reacted by Paul Crockett, Ctibor Laky and Tino Rüb
Metadata
Metadata
Assignees
Labels
area: coreIssues related to the framework runtimeIssues related to the framework runtimefeatureLabel used to distinguish feature request from other issuesLabel used to distinguish feature request from other issuesfreq1: low
Activity
DzmitryShylovich commentedon Nov 12, 2016
Services already have
ngOnDestroyhook so it can be closed.zoechi commentedon Nov 14, 2016
I have never seen it mentioned that
ngOnDestroyis supported on services.The docs say "when a directives or pipe is destroyed" https://angular.io/docs/ts/latest/api/core/index/OnDestroy-class.html
DzmitryShylovich commentedon Nov 14, 2016
http://plnkr.co/edit/AgBYNxmW1aIPiDFAr5iu?p=preview
zoechi commentedon Nov 14, 2016
I guess the docs on the interface should be updated then
docs(core): update OnDestroy description (#13369)
docs(core): update OnDestroy description (#13369)
maxkoretskyi commentedon Jun 7, 2017
@DzmitryShylovich, there is no longer logging in the console in the plunker you referenced when a component is destroyed. Has anything changed?
willshowell commentedon Jun 29, 2017
@MaximusK there was a change in 4.0.0-rc.4 that made providers instantiate lazily.
Updated plunker: http://plnkr.co/edit/FA9bIc3dEiHundiKx95M?p=preview
10 remaining items
gparlakov commentedon Apr 15, 2018
@aks1994 This is my understanding of what happens:
Right?
(I am not aware of a way of instructing angular to kill off any module or its providers.)
Provided that you already have guards: Maybe inside of a route guard that is executed on the way in you can clean up/initialize the service i.e. every time user wants to go back to this component the service-s state gets zeroed out.
Alternatively the service could become a provider of a service-s instead of doing the work itself.
aks1994 commentedon Apr 15, 2018
gparlakov commentedon Apr 15, 2018
@aks1994
For the clean up - I would do it just like you said - set everything back to initial value. And do it /initialize it/ every time you want to use it. The risk is that there might be a confusion about whether or not the state was initialized - so I'd do it every time.
Elaborating on the provider of services: here. Notice the 'the-service.service.ts' and how it is provided in the module and used in
hello.component.tsandapp.component.ts. It is providing a new instance for every time we call the.provideAService('somestring')method.aks1994 commentedon Apr 16, 2018
@gparlakov
Okay, makes sense. Thanks for the help and sharing the info on provider of services!
jscharett commentedon Jul 6, 2018
This seems like a bit of a hack, imo. It would be nice to simply specify my provider in the module and allow the module to destroy it when the user exits the module. The current design can be left in place for backwards compatibility, but why not allow me to specify that the provider gets destroyed every time the use exits the module?
mlc-mlapis commentedon Jul 6, 2018
@jscharett ... what is the term
exit from the module? What it means for you.jscharett commentedon Jul 6, 2018
@mlc-mlapis When my route changes to leave a lazy loaded module. I understand that lazy loading only delays the loading of the module and does not "unload" it when navigating away from it. It just seems like there should be a clean way to "reset/destroy" a provider used in a lazy loaded module.
For example, in my app, we have a lazy loaded module that when the user enters, create a provider for storing various data. The provider is used across multiple components, so its created in the ng module. When the user navigates away from the module back to the home page, I am required to implement a guard so that I can "cleanup" the data stored in the provider. Not a huge issue, but just seems like it would be beneficial if you could specify a provider that could be destroyed upon exiting the module/route.
It was not intuitive to me that my provider would continue after navigating away from the module.
Sahil624 commentedon Feb 22, 2019
Hi !
I am also facing same issue. My provider stores some user data that is shared among one or more components for a logged in user. When user logs out and login with any other account user data of previous user is shown in every component.
Any solution or workaround available ?
Thanks for any help.
shikharseth commentedon May 9, 2019
@Sahil624 any solution you found out for your use case?
It would be great if you can help me in that too
gparlakov commentedon May 9, 2019
@Sahil624 @shikharseth One approach would be providing the provider in the component that needs it. Then It will get instantiated and destroyed along with the component. I am assuming this component would get destroyed when user logs out - because app navigates to logout screen for example
shikharseth commentedon May 9, 2019
@gparlakov the use case is quite different here. Since, I require service data to be shared across components so I need to mention my providers inside my app.module.ts. Your's approach wont let me do the same.
Data sharing is working fine as to my need across different module and component.
But the scenario is when I logout from one user and login with different app.module don't get destroyed(though component do), due to this service data remains intact and I get same data of my last user on sigining with different user.
I want to destroy data from my services data defined in app.module
gparlakov commentedon May 22, 2019
@shikharseth It appears that you need to use the onDestroy lifecycle hook to clean up your service.
Or the logout method needs to actually clear the state of that service. Either way I would create a method on that service
onLogoutand call it.Sahil624 commentedon May 22, 2019
Hi !
Sorry didn't knew about your reply earlier.I did this by making an event service. It was basically a subject in service and I subscribed it in my services which I wanted to destroy (More like i wanted to clear data that was cached in that service). In my logout function i emitted a event (subjectName.next()). Whenever is received anything in by event subscription I cleared my data.
This is more of a hack. But it was working for me. I cannot share my code at this time but i hope I could explain it will. Feel free in any case of doubt.
Thanks
angular-automatic-lock-bot commentedon Sep 15, 2019
This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.
Read more about our automatic conversation locking policy.
This action has been performed automatically by a bot.