diff --git a/apps/browser/src/popup/app.component.ts b/apps/browser/src/popup/app.component.ts
index 7f401461b1..504abbe158 100644
--- a/apps/browser/src/popup/app.component.ts
+++ b/apps/browser/src/popup/app.component.ts
@@ -1,7 +1,15 @@
-import { ChangeDetectorRef, Component, NgZone, OnInit, SecurityContext } from "@angular/core";
+import {
+ ChangeDetectorRef,
+ Component,
+ NgZone,
+ OnDestroy,
+ OnInit,
+ SecurityContext,
+} from "@angular/core";
import { DomSanitizer } from "@angular/platform-browser";
import { NavigationEnd, Router, RouterOutlet } from "@angular/router";
import { IndividualConfig, ToastrService } from "ngx-toastr";
+import { Subject, takeUntil } from "rxjs";
import Swal, { SweetAlertIcon } from "sweetalert2";
import { AuthService } from "@bitwarden/common/abstractions/auth.service";
@@ -23,10 +31,12 @@ import { routerTransition } from "./app-routing.animations";
`,
})
-export class AppComponent implements OnInit {
+export class AppComponent implements OnInit, OnDestroy {
private lastActivity: number = null;
private activeUserId: string;
+ private destroy$: Subject = new Subject();
+
constructor(
private toastrService: ToastrService,
private broadcasterService: BroadcasterService,
@@ -46,7 +56,7 @@ export class AppComponent implements OnInit {
// Clear them aggressively to make sure this doesn't occur
await this.clearComponentStates();
- this.stateService.activeAccount.subscribe((userId) => {
+ this.stateService.activeAccount.pipe(takeUntil(this.destroy$)).subscribe((userId) => {
this.activeUserId = userId;
});
@@ -121,7 +131,7 @@ export class AppComponent implements OnInit {
BrowserApi.messageListener("app.component", (window as any).bitwardenPopupMainMessageListener);
- this.router.events.subscribe(async (event) => {
+ this.router.events.pipe(takeUntil(this.destroy$)).subscribe(async (event) => {
if (event instanceof NavigationEnd) {
const url = event.urlAfterRedirects || event.url || "";
if (
@@ -146,6 +156,11 @@ export class AppComponent implements OnInit {
});
}
+ ngOnDestroy(): void {
+ this.destroy$.next();
+ this.destroy$.complete();
+ }
+
getState(outlet: RouterOutlet) {
if (outlet.activatedRouteData.state === "ciphers") {
const routeDirection =
diff --git a/apps/desktop/src/app/app.component.ts b/apps/desktop/src/app/app.component.ts
index 300104ee72..9732173b56 100644
--- a/apps/desktop/src/app/app.component.ts
+++ b/apps/desktop/src/app/app.component.ts
@@ -10,6 +10,7 @@ import {
import { DomSanitizer } from "@angular/platform-browser";
import { Router } from "@angular/router";
import { IndividualConfig, ToastrService } from "ngx-toastr";
+import { Subject, takeUntil } from "rxjs";
import { ModalRef } from "@bitwarden/angular/components/modal/modal.ref";
import { ModalService } from "@bitwarden/angular/services/modal.service";
@@ -96,6 +97,8 @@ export class AppComponent implements OnInit {
private isIdle = false;
private activeUserId: string = null;
+ private destroy$: Subject = new Subject();
+
constructor(
private broadcasterService: BroadcasterService,
private tokenService: TokenService,
@@ -127,9 +130,10 @@ export class AppComponent implements OnInit {
) {}
ngOnInit() {
- this.stateService.activeAccount.subscribe((userId) => {
+ this.stateService.activeAccount.pipe(takeUntil(this.destroy$)).subscribe((userId) => {
this.activeUserId = userId;
});
+
this.ngZone.runOutsideAngular(() => {
setTimeout(async () => {
await this.updateAppMenu();
@@ -360,6 +364,8 @@ export class AppComponent implements OnInit {
}
ngOnDestroy() {
+ this.destroy$.next();
+ this.destroy$.complete();
this.broadcasterService.unsubscribe(BroadcasterSubscriptionId);
}