From c2b4ec2195c3a78ba1fc06ad6da4281cef96b7d4 Mon Sep 17 00:00:00 2001 From: markuczy Date: Tue, 16 Jul 2024 08:13:35 +0200 Subject: [PATCH] feat: router unsubscribe for remote components --- .../lib/utils/webcomponent-bootstrap.utils.ts | 32 ++++++++++++++----- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/libs/angular-webcomponents/src/lib/utils/webcomponent-bootstrap.utils.ts b/libs/angular-webcomponents/src/lib/utils/webcomponent-bootstrap.utils.ts index 7a3ec014..1e536d61 100644 --- a/libs/angular-webcomponents/src/lib/utils/webcomponent-bootstrap.utils.ts +++ b/libs/angular-webcomponents/src/lib/utils/webcomponent-bootstrap.utils.ts @@ -1,6 +1,7 @@ import { createCustomElement } from '@angular/elements' import { createApplication, platformBrowser } from '@angular/platform-browser' import { + EnvironmentInjector, EnvironmentProviders, Injector, NgModuleRef, @@ -16,7 +17,7 @@ import { import { Router } from '@angular/router' import { getLocation } from '@onecx/accelerator' import { EventsTopic } from '@onecx/integration-interface' -import { filter } from 'rxjs' +import { Subscription, filter } from 'rxjs' /** * Implementation inspired by @angular-architects/module-federation-plugin https://github.com/angular-architects/module-federation-plugin/blob/main/libs/mf-tools/src/lib/web-components/bootstrap-utils.ts @@ -59,10 +60,25 @@ export async function bootstrapRemoteComponent( cachePlatform(production) adaptRemoteComponentRoutes(app.injector) - connectMicroFrontendRouter(app.injector, false) + const sub = connectMicroFrontendRouter(app.injector, false) + + createEntrypoint(component, elementName, app.injector, sub) +} + +export function createEntrypoint( + component: Type, + elementName: string, + injector: EnvironmentInjector, + routerSub?: Subscription | null +) { + let originalNgDestroy = component.prototype.ngOnDestroy?.bind(component) + component.prototype.ngOnDestroy = () => { + routerSub?.unsubscribe() + originalNgDestroy() + } const myRemoteComponentAsWebComponent = createCustomElement(component, { - injector: app.injector, + injector: injector, }) customElements.define(elementName, myRemoteComponentAsWebComponent) @@ -124,25 +140,25 @@ function cachePlatform(production: boolean): PlatformRef { return platform } -function connectMicroFrontendRouter(injector: Injector, warn: boolean = true) { +function connectMicroFrontendRouter(injector: Injector, warn: boolean = true): Subscription | null { const router = injector.get(Router) if (!router) { if (warn) { console.warn('No router to connect found') } - return + return null } - connectRouter(router) + return connectRouter(router) } -function connectRouter(router: Router): void { +function connectRouter(router: Router): Subscription { const initialUrl = `${location.pathname.substring(getLocation().deploymentPath.length)}${location.search}` router.navigateByUrl(initialUrl) let lastUrl = initialUrl const observer = new EventsTopic() - observer.pipe(filter((e) => e.type === 'navigated')).subscribe(() => { + return observer.pipe(filter((e) => e.type === 'navigated')).subscribe(() => { const routerUrl = `${location.pathname.substring(getLocation().deploymentPath.length)}${location.search}` if (routerUrl !== lastUrl) { lastUrl = routerUrl