Angular route guards - redirection/refresh loop on Firefox

53 Views Asked by At

I have this route guard that returns an observable, which checks for certain conditions before either:

  • activating navigation
  • redirecting somewhere outside the app
  • redirecting to an internal route
@Injectable({
  providedIn: 'root'
})
export class LandingPageGuard implements CanActivate {
  public constructor(
    private readonly _router: Router,
    private readonly _coreFacade: CoreFacade,
    private readonly _previewFacade: PreviewFacade
  ) {}

  public canActivate(): Observable<boolean> {
    return combineLatest([
      this._coreFacade.initialLoadCompleted$,
      this._coreFacade.isLandingPageEnabled$,
      this._coreFacade.isIasEnabled$,
      this._previewFacade.isPreviewModeEnabled$
    ]).pipe(
      skipWhile(([initialLoadCompleted]) => !initialLoadCompleted),
      map(([, isLandingPageEnabled, isIasEnabled, isPreviewEnabled]) => {
        if (isLandingPageEnabled || isPreviewEnabled) {
          return true;
        } else if (isIasEnabled) {
          window.location.href = `${window.location.origin}/bff/login`;
        } else {
          this.routeToLoginPage();
        }

        return false;
      })
    );
  }

  public routeToLoginPage() {
    this._router.navigate([LOGIN_ROUTE], { state: { from: 'landing-page' } });
  }
}

The window.location.href line is what I'm having problems with. As soon as redirection occurs, the page refreshes many times before actually performing the redirection. Sometimes it won't even stop, as if stuck in some kind of loop. Do you have any idea of what could be causing this?

It's worth noting that this only happens on Firefox. Also, redirection needs to go to ${window.location.origin}/bff/login because that's an endpoint in a microservice that works under the same domain.

I've come up with a couple of workarounds:

  • return a UrlTree so navigation starts to another route, which has a guard that will do the actual redirection to the microservice. We just upgraded to Angular v14 so this new guard is a functional one. This, for reasons unknown, works and doesn't trigger the redirection loop
  • dispatch an action from the original route guard and delegate the redirection to the microservice to an effect

Even though these work, I wonder if there's a better solution? and what is causing this to happen?

0

There are 0 best solutions below