i want to redirect from the empty path " " to my login page, when user is not logedd in. So i'm using guards and children routes to do this. However, my code is fine to all routes except " ".
This is my guard (canValidate function)
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot):boolean {
return this.canMethod();
}
canMethod () {
if (Environment.ActivateGuard) {
let token = this._auth.getCookie(AuthorizationEnum.cookieName);
if(token) { // token exists
let data = {
token: token,
module: this.module
};
this._auth.validate(data, AuthorizationEnum.Bearer).subscribe(
data => { // valid token
if ( data.res == AuthorizationEnum.emptyResponse) { // invalid user, it doesn't belongs to this module.
this.letsRedirect();
}
else {
let user_role = data.det[1]; // this is the user's role!.
}
},
error => { // other error
this.letsRedirect();
}
);
return true;
}
else { // user don't have token
this.letsRedirect();
}
}
else {
return true;
}
}
letsRedirect(){
window.location.href = Environment.authAppUrl + AuthorizationEnum.redirectQuery + encodeURIComponent(this.url);
}
And this is my app-routing.module.ts(only the array of routes)
const routes: Routes = [
// TODO: Validar esta ruta
//{ path: '', component: LoginComponent, pathMatch: 'full' },
//Con header
{
path: '',
children: [
{ path: '', component: HomeComponent,canActivate:[AuthorizatedGuard]},
{ path: 'inicio', component: HomeComponent, canActivate:[AuthorizatedGuard] },
{ path: 'categorias', redirectTo: 'base-lista/categorias'},
{ path: 'videos', redirectTo: 'base-lista/videos'},
{ path: 'base-lista/:idList', component: BaseListComponent, canActivate:[AuthorizatedGuard] },
{ path: 'base-lista/categorias/gestionar-categorias', component: CategoryVideoComponent, canActivate:[AuthorizatedGuard] },
{ path: 'base-lista/categorias/ver-detalles-categoria', component: ViewDetailsCategoryComponent, canActivate:[AuthorizatedGuard] },
{ path: 'base-lista/videos/gestionar-videos', component: VideoComponent, canActivate:[AuthorizatedGuard] },
{ path: 'base-lista/videos/ver-detalles-video', component: ViewDetailsVideoComponent, canActivate:[AuthorizatedGuard] },
],
component: AppLayoutComponent,
canActivate: [AuthorizatedGuard],
},
//sin header
{
path: '',
component: LoginComponent,
children: [
{
path: 'login',
component: LoginComponent
}
]
}
];
When we try to access "htpp://localhost:4200/", Angular will evaluate the route paths. The first part of the path for the first route configured is "", so let’s continue evaluating the second part which is also "", so we have a match! But the guard still need to verify if the user can access the HomeLayoutComponent (if user is logged in). If the user is logged in, then the access is granted and the user will see the HomeLayoutComponent (the navbar along with the HomeComponent being rendered in the router-outlet), otherwise it is redirected to "htpp://localhost:4200/login".
So suppose we are trying to access "htpp://localhost:4200/login". Angular will evaluate the route path again. The first part of the path for the first route configured is "", so let’s continue evaluating the second part which is "login", so we do not have a match with. We need to evaluate the next route configured. Let’s go again! The first part of the path for the first route configured is "" (this time), so let’s continue evaluating the second part which is "login" and we have a match . In this case the LoginLayoutComponent is displayed. Since there is only a router-outlet in the HTML template, only the LoginComponent will be displayed.
I am using this link to create the routing
So.. what is wrong with my code?
This work for me
[
{
path: '',
pathMatch: 'full',
redirectTo: 'teams'
},
{
path: 'teams',
component: TeamsComponent
}
]
Reference - http://vsavkin.tumblr.com/post/146722301646/angular-router-empty-paths-componentless-routes
I managed to solve my problem, including the empty route without the guard redirecting to the login page, so that if the person is not logged in he will redirect him to login otherwise, he will enter the following definition always ensuring that the person already this logged in the system.
const routes: Routes = [
// Sin header
{ path: '', component: LoginComponent, pathMatch: 'full' },
//Con header
{
path: '',
children: [
{ path: '', component: HomeComponent,canActivate:[AuthorizatedGuard]},
{ path: 'inicio', component: HomeComponent, canActivate:[AuthorizatedGuard] },
{ path: 'categorias', redirectTo: 'base-lista/categorias'},
{ path: 'videos', redirectTo: 'base-lista/videos'},
{ path: 'base-lista/:idList', component: BaseListComponent, canActivate:[AuthorizatedGuard] },
{ path: 'base-lista/categorias/gestionar-categorias', component: CategoryVideoComponent, canActivate:[AuthorizatedGuard] },
{ path: 'base-lista/categorias/ver-detalles-categoria', component: ViewDetailsCategoryComponent, canActivate:[AuthorizatedGuard] },
{ path: 'base-lista/videos/gestionar-videos', component: VideoComponent, canActivate:[AuthorizatedGuard] },
{ path: 'base-lista/videos/ver-detalles-video', component: ViewDetailsVideoComponent, canActivate:[AuthorizatedGuard] },
],
component: AppLayoutComponent,
canActivate: [AuthorizatedGuard],
},
];
ps: sorry for my english
Have you tried removing the ''
path from your LoginComponent
? It seems redundant. Unless you are using a separate layout in which case you need to specify the layout component your are using (like your AppLayoutCompnent
) and not the LoginComponent
twice.
change
{
path: '',
component: LoginComponent,
children: [
{
path: 'login',
component: LoginComponent
}
]
}
to just
{
path: 'login',
component: LoginComponent
}
OR
{
path: '',
component: LoginLayoutComponent, // <---
children: [
{
path: 'login',
component: LoginComponent
}
]
}
Another thing you should look at is using the router to handle the redirect instead of window.location
. It's the "Angular" way to handle it. Inject Router
into your guard and use it to navigate.
letsRedirect(){
this.router.navigate(['/login'], { queryParams: { redirectUrl: this.url } });
}
Finally, you can simplify the routes by using CanActivateChild
. It will perform the check for all child routes instead of adding the guard to each.
{
path: '',
children: [
{ path: '', component: HomeComponent,
{ path: 'inicio', component: HomeComponent },
{ path: 'categorias', redirectTo: 'base-lista/categorias'},
{ path: 'videos', redirectTo: 'base-lista/videos'},
{ path: 'base-lista/:idList', component: BaseListComponent },
{ path: 'base-lista/categorias/gestionar-categorias', component: CategoryVideoComponent },
{ path: 'base-lista/categorias/ver-detalles-categoria', component: ViewDetailsCategoryComponent },
{ path: 'base-lista/videos/gestionar-videos', component: VideoComponent },
{ path: 'base-lista/videos/ver-detalles-video', component: ViewDetailsVideoComponent },
],
component: AppLayoutComponent,
canActivateChild: [AuthorizatedGuard],
},
and update your guard to
canActivateChild(route: ActivatedRouteSnapshot, state: RouterStateSnapshot):boolean
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With