'Guard not re-routing to other component

I have these two guards

@Injectable({
 providedIn: 'root'
})
export class DesktopGuard implements CanActivate {
  constructor(
    private router: Router,
    private route: ActivatedRoute,
  ) { }

  canActivate() {
    if (window.innerWidth < 768) {
      this.router.navigate(['./mobile'], {relativeTo: this.route.parent});
      return false;
   }
   return true;
 }
}
@Injectable({
 providedIn: 'root'
})
export class MobileGuard implements CanActivate {
  constructor(
    private router: Router,
    private route: ActivatedRoute,
  ) { }

  canActivate() {
    if (window.innerWidth > 768) {
     this.router.navigate(['./welcome'], {relativeTo: this.route.parent});
     return false;
    }
   return true;
 }
}

And these routes.

const routes: Routes = [
  {
    path: '',
    redirectTo: 'grid/welcome',
    pathMatch: 'full',
  },
  {
    path: 'grid',
    component: GridContainerComponent,
    children: [
      {
        path: 'mobile',
        canActivate: [MobileGuard],
        component: WelcomeMobileComponent,
      },
      {
        path: 'welcome',
        canActivate: [DesktopGuard],
        component: WelcomeComponent
      },

    ]
  },
];

Guard should prevent the component from loading and redirect based on the window size. My issue is the redirect to ./mobile, it keeps re-running the guard and consuming memory, i.e it will not redirect to WelcomeMobileComponent. I suspect the router is to blame, but I am not sure.

Any ideas?

thanks!



Solution 1:[1]

I didn't find the reason for this re-route to the same guard.

However, for those looking for a solution to the overall problem of routing based on window size, try this.

Use the BreakpontObserver object and route accordingly.

export class AppComponent {
  constructor(
    private router: Router,
    private breakpointObserver: BreakpointObserver) {
        this.breakpointObserver.observe([
          "(max-width: 768px)"
        ]).subscribe((result: BreakpointState) => {
          if (result.matches) {
             this.router.navigate(['/photo-search/grid/mobile']);   
          } else {
            this.router.navigate(['/photo-search/grid/desktop']);
          }
        });
      }
}

This solved it for me.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 godhar