angularrxjsangular-routerangular-router-guards

How to unsubscribe from RxJs subject within an Angular functional route guard


I have a simple Angular functional route guard that retrieves a boolean value from a Subject<boolean> property on a service. The guard seems to work as expected and looks like this:

export const isConfigValidGuard = () => {
  const configService = inject(ConfigService);
  const notificationService = inject(NotificationService);
  const router = inject(Router);

  configService.configValidation$.subscribe({
    next: (isValid) => {
      if (isValid) {
        return true;
      } else {
        notificationService.warn('invalid config, redirecting to home');
        return router.parseUrl('/home');
      }
    }
  });
};

My question is do I need to unsubscribe the subscription to configService.configValidation$ and, if so, how. Again, the type of configService.configValidation$ is Subject<boolean>.


Solution

  • Yes, you need to unsubscribe or take(1) in order to prevent memory leaks.

    You could also avoid manual subscription and let Angular handle it for you by returning directly an Observable!

    export const isConfigValidGuard = () => {
      const configService = inject(ConfigService);
      const notificationService = inject(NotificationService);
      const router = inject(Router);
    
      configService.configValidation$.pipe(
        map((isValid) => {
          if (isValid) {
            return true;
          } else {
            notificationService.warn('invalid config, redirecting to home');
            return router.parseUrl('/home');
          }
        })
      );
    };
    

    Since the Subject already contains a boolean we can return its value, and handle only the case where it is false.