How to redirect from parent route to child route in Angular canActivate guard?
Asked Answered
C

1

7

I've got this routes

AppRouting

{
   path: 'user',
   canLoad: [AuthGuard],
   loadChildren: () =>
   import('./user/user.module').then((m) => m.PublicUserModule)
}

UserRouting

{
    path: '',
    component: PublicUserPageComponent,
    canActivate: [UserPhonesCheckGuard],
    children: [
      /*{
        path: '',
        pathMatch: 'full',
        redirectTo: 'check'
      },*/
      {
        path: 'account',
        loadChildren: () =>
          import('./account/user-account.module').then(
            (m) => m.PublicUserAccountModule
          )
      },
      {
        path: 'check',
        loadChildren: () =>
          import('./check/user-check.module').then(
            (m) => m.PublicUserCheckModule
          )
      }
    ]
  }

Using UserPhonesCheckGuard depending on some conditions I want to redirect or to the check or to account children route but with

canActivate() 
    return this.router.parseUrl('/user/check');
  }

the browser go nuts :(

What path should I use?

Condyle answered 19/5, 2020 at 16:55 Comment(0)
T
9

In this way;

canActivate() 
    return this.router.parseUrl('/user/check');
}

an infinite loop occurs.

Because when you return a UrlTree (which is returned by this.router.parseUrl) from canActivate current navigation is cancelled and a new navigation started.

Since new navigation is going to a sub url (child) of current navigation, canActivate guard runs again for the new navigation which in turn causes an infinite loop.

That's why you need a way to detect child navigation in canActivate and break the infinite loop. One way of detecting child navigation can be to control the url. Such as;

canActivate(next: ActivatedRouteSnapshot,state: RouterStateSnapshot) {
  console.log(state.url)

  if(state.url === "/user/check" || state.url === "/user/account") 
    return true;

  if(someCondition) /* here you determine which child to navigate */
    return this.router.parseUrl('/user/check');
  else
    return this.router.parseUrl('/user/account');
}

I created a simple demo here. In the demo, you can see in the console that canActivate runs twice for every navigation. One for the parent navigation and one for the child navigation. Without if condition, parent navigation would run indefinitely.

I hope it helps.

Trophic answered 19/5, 2020 at 22:42 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.