angular: Destroying lazy loaded modules doesn't unload them

I’m submitting a…


[x] Feature request

Current behavior

Currently the lazy loaded module sets itself to the destroyed state. When we revisit the lazy route, it still loads the already-destroyed module. It doesn’t unset itself.

Destroying it for a second time results in:

'Error: The ng module LazyModule has already been destroyed.'

Expected behavior

I expect lazy modules to unload themselves once destroyed, re-initializing themselves when they’re needed again.

What is the motivation / use case for changing the behavior?

Our application has to manage multiple users. Our services build up a toxic cache of data that belongs to user Alice. When we switch to user Bob, we call destroy() on the lazy loaded module and reload the module for Bob.

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Reactions: 36
  • Comments: 36 (9 by maintainers)

Commits related to this issue

Most upvoted comments

@BenDevelopment

Route to a location outside of the lazy module before destroying it.

onDestroy() {
  routeToViewOutsideOfLazyModule();
  this.lazy.destroy();
}

Ok - so if the user is logging out, after the session is cleared, why can’t you force the window to reload? Doesn’t that solve the problem? setTimeout(()={window.location.href=restartLocation;},1)

On Thu, Jun 10, 2021 at 3:44 AM Eddy @.***> wrote:

@ShamimIslam https://github.com/ShamimIslam I globally agree with you about : “If you need to destroy a lazy loaded module to clear your data / avoid memory leak, your problem is elsewhere”.

But I still want this feature because I have the following use case :

I have a huge “macro app” which assemble different tools for all the different job in the same company. Each employee is allowed to use some of the tools. I have a kind of plugin system (based among other thing on lazy loading via the router) where each tool is a plugin / NgModule and each time a user log in, based on the user permissions, I’m loading only the allowed tools. But when the user logout, I specifically need to unload all the tools because the next user to login might not have the same permissions and therefor will not load the same tools. In my case, it’s not about clearing data, it’s about “clearing / unloading code OR destroying instances” the next user will not be allowed to use.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/angular/angular/issues/24962#issuecomment-858393105, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAXKQTS4MOGPIBOLATK5UOTTSBUMPANCNFSM4FKTMA2A .

@mlc-mlapis As @kewde explained here https://github.com/angular/angular/issues/24962#issuecomment-406380151, yes there is a destroy() method which destroys the Injector (and call the methods ngOnDestroy on all services inside this injector) + call the registered onDestroy callbacks on the NgModuleRef itself.

But the ngModule instance (or NgModuleRef) itself is not cleared as there is still a reference to it inside the router inside a LoadedRouterConfig as the module attribute => https://github.com/angular/angular/blob/dfb072a93c2b49a02f1c36bf3e5f9547f26af29d/packages/router/src/config.ts#L501

This attribute is never cleared and therefor the NgModuleRef is never gc’ed.

On the other hand, the NgComponentOutlet does clear the reference to the NgModule instance : https://github.com/angular/angular/blob/dfb072a93c2b49a02f1c36bf3e5f9547f26af29d/packages/common/src/directives/ng_component_outlet.ts#L97

Our application has to manage multiple users. Our services build up a toxic cache of data that belongs to user Alice. When we switch to user Bob, we call destroy() on the lazy loaded module and reload the module for Bob.

@kewde can you explain me how to call destroy() on a lazy loaded module ? I cannot find any documentation about that.