Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular 2: Redirect route with parameters and optional parameters

I want to redirect a route to another route:

/foo/bar/123 schould redirect to /bar/123;mode=test

I configured the route in the following way:

{ path: 'foo/bar/:id', redirectTo: '/bar/:id;mode=test' },

When it is redirecting, the ;mode=test part is missing in the target url. How can I include this?

like image 637
Johni Avatar asked Aug 25 '17 10:08

Johni


1 Answers

The angular router basically looks at path objects and creates the set of basic routes of your app (without the optional parameters). Which then would be used to recognise routes if they match the path exactly. So the optional parameters cannot be used inside them because they're "optional". And the only way to include any route params in these path objects, is binding them inside the url with':something' syntax which then wouldn't be optional. I think you have some other ways to cover this need of yours:

Adding your "mode" parameter to your basic route: You can define a path like this: { path:'/bar/:id/:mode', component: BarComponent } and change your redirect path to { path: 'foo/bar/:id', redirectTo: '/bar/:id/test' }

Using a proxy component: Change the redirect path to: { path: 'foo/bar/:id', component: BarProxyComponent } , and define that component like this:

export class BarProxyComponent {
   constructor(private _router: Router, private _route: ActivatedRoute){
      _router.navigate(['/bar/'+_route.snapshot.params['id'],{mode: 'test'}]);
   }   
}

Using a canActivate Guard: You can also create a guard service for your 'foo' path, and inside the guard redirect it to the route you want. However, it's not exactly the real intention behind these guards and it's just taking advantage of them for that said problem. You can change the redirect path to { path: 'foo/bar/:id', component: UnusedFooComponent, canActivate: [FooGuard]} and define the guard like this:

@Injectable()
export class FooGuard implements CanActivate {
  
constructor(private _router: Router){}
   canActivate(route: ActivatedRouteSnapshot) {
      this._router.navigate(['/bar/'+route.params['id'],{mode: 'test'}]);
      return false;
   }
}

Also don't forget to provide the FooGuard at a module level. And note that here, you're always redirecting to another place (and returning false) in the guard before the UnusedFooComponent is created...

like image 149
GHB Avatar answered Sep 29 '22 12:09

GHB