I am attempting to use module federation along with ngrx store & ngrx effects in my webapp which is all in working order for the most part. However, I wish to destroy my NgModuleRef
when switching to another lazy loaded route. Hence if I have one module called MyAccountModule at /myaccount and another module called Dashboard at /dashboard then I wish to destroy the MyAccountModule when switching to the /dashboard route and destroy the /dashboard route when switching back to /myaccount.
I have achieved this using this code:
export class MyAccountModule implements OnDestroy {
private destroyed$ = new Subject<boolean>();
constructor(
private router: Router,
private currentNgModuleRef: NgModuleRef<MyAccountModule>,
private store: Store<AppState>,
private webSocket: WebsocketService
) {
this.store.dispatch(new InitializeMyAccountModuleAction());
this.router.events
.pipe(
filter((event) => event instanceof NavigationEnd),
takeUntil(this.destroyed$),
map(event=> event as RouterEvent)
)
.subscribe(($evt)=>{
if (!$evt.url.includes('myaccount')){
this.currentNgModuleRef.destroy();
}
});
}
ngOnDestroy() {
this.store.removeReducer('manageAccountState');
if (this.webSocket.sockets.has(environment.wsURL)) this.store.dispatch(new WebsocketDisconnectAction({ wsURL: environment.wsURL }));
this.destroyed$.next(true);
this.destroyed$.complete();
}
This works fine and both routes seem to display & function correctly. However, if you were to route from /myaccount to /dashboard & then back to /myaccount for example. It seems upon the reinitialising of MyAccountModule (/myaccount), it does not appear to reinstantiate EffectsModule.forFeature()
. Meaning that when I trigger an ngrx effect it uses the original R3Injector
therefore when calling a service within the effect such as a http service it lacks the relevant providers because the instance of the injector is that of the initially loaded module which is now in a destroyed state. Meaning for some reason or another ngrx does not seem to update the state surrounding the running of the contents of createEffect(()=>
to utilise the newest instance of R3Injector
.
Therefore I guess my question becomes is there a way to manually destroy EffectsModule.forFeature()
from memory? If not, is it possible to de-register the effect? Or some way of re-initialising the injector instance provider for the module within the constructor.
The error received is due to it being thrown in core.js
:
assertNotDestroyed() {
if (this._destroyed) {
throw new Error('Injector has already been destroyed.');
}
}
where this = R3Injector
and the value of R3Injector properties includes _destroyed:true
due to it being the previous instance.
Thanks in advance for any assistance.