How to redirect to child route from guard in angular
Asked Answered
A

1

8

How do I redirect to a child route from a guard of the parent route while also protecting child routes from direct access*?

Problem with absolute navigation the guard on the parent component is called again in a loop when navigating to the child route.

Problem with relative navigation is that the guard is protecting the parent route so there is no Activated Route yet to navigate relative to. Also this would probably not protect child routes. Maybe the same guard could also be used with the child routes or with CanActivateChildren.

Stackblitz Example: https://stackblitz.com/edit/angular-qbe2a7

routes

const appRoutes: Routes = [
  {
    path: 'foo',
    component: FooComponent,
    canActivate: [ RedirectionGuard ],
    children: [
      {
        path: 'foo-child',
        component: FooChildComponent
      }
    ]
  }
];

canActivate() in guard

canActivate(
    route: ActivatedRouteSnapshot,
    state: RouterStateSnapshot
  ): Observable<boolean>|Promise<boolean>|boolean {

    console.log('guard: ', route, state, this.route);

    // idea: create own ActivatedRoute and give it the values from ActivatedRouteSnapshot which knows about 'foo/'
    const foo: ActivatedRoute = new ActivatedRoute();
    console.log(foo);

    // Error: Cannot match any routes
    // I think because there is no route to be relative to when canActivat is called. Router has not yet navigated to '/foo/'
    this.router.navigate(['../foo-child'], {               relativeTo: this.route
    });

    // Errors with infinite loop because '/foo/' has this guard which will then be called again
    //this.router.navigate(['/foo/foo-child']);

    // navigate returns true also. maybe just return that.
    return true;
  }

*Why not add guards to all childs you may ask. I need to redirect from the parent route to many different child routes depending on the state of the app. I am currently using one of the child routes to redirect from that component but that does not protect child routes form direct navigation by the user.

Alric answered 25/9, 2018 at 23:11 Comment(2)
are you trying to redirect from one child component to another child component or from a component to another component's child?Eudoxia
From a parent route to one of its child routes.Alric
A
3

One way to achieve this could be to use url params, use canActivateChild and redirectTo a child route when entering the parent route.

StackBlitz Example: https://stackblitz.com/edit/angular-redirect-with-params

routing

const appRoutes: Routes = [
  {
    path: 'foo',
    component: FooComponent,
    canActivateChild: [ RedirectionGuard ],
    children: [
      {
        path: '',
        pathMatch: 'full',
        redirectTo: 'foo-child-1'
      },
      {
        path: 'foo-child-1',
        component: FooChildComponent
      },
       {
        path: 'foo-child-2',
        component: FooChildComponent
      }
    ]
  },
];

guard

canActivate(
    route: ActivatedRouteSnapshot,
    state: RouterStateSnapshot
  ): Observable<boolean>|Promise<boolean>|boolean {

    console.log('params:', route.params, route.url);
    if (!route.params.skip) {
      this.router.navigate(['/foo/foo-child-2', { skip: true }], {
        queryParams: { skip: 1 }
      });
    }

    return true;

  }

  canActivateChild(
    route: ActivatedRouteSnapshot,
    state: RouterStateSnapshot
  ) {
    return this.canActivate(route, state);
  }
Alric answered 26/9, 2018 at 14:2 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.