angular2: how to get Full path on CanLoad guard while maintaining redirect url
I am using angular 2.4 version and router version "^3.4.10".
I am trying to handle redirect url using auth guard service.
When user hit url 'domain/assignment/3/detail' and if user is not login then user redirected to 'domain/login' page. and when user successfully login in to system then redirected to 'domain/assignment/3/detail' previous url which user tries to access.
I have implemented CanLoad guard on assignment module. so when user tries to access url 'domain/assignment/3/detail' and if user is not login, url stores into redirectUrl property of authservice (this.authService.redirectUrl).
so here is the issue comes in my case. i am not able to get full path of the url which user hit. i am getting 'assignment' instead 'assignment/3/detail' within CanLoad guard. how can i get full path so that i can redirect user to proper path within CanLoad guard.
CanLoad:
canLoad(route: Route): boolean {
let url = `/${route.path}`; // here i got url path 'assignment' instead 'assignment/3/detail'
return this.checkLogin(url);
}
Main routing app.routes.ts
const routes: Routes = [
{ path: '', redirectTo: 'login', pathMatch: 'full' },
{ path: 'login', component: LoginComponent},
{
path: 'assignment',
loadChildren: './assignment/assignment.module#AssignmentModule',
canLoad: [AuthGuard]
},
{ path: '**', redirectTo: '', pathMatch: 'full' }];
Assignment routing: assignment-routing.ts
const assignmentRoutes: Routes = [
{
path: '',
component: AssignmentComponent,
canActivate: [AuthGuard]
children: [
{
path: '',
canActivateChild: [AuthGuard],
children: [
{
path: ':assignmentId/detail', component: AssignmentDetailComponent,
canActivate: [AuthGuard]
}
]
}]
}];
AuthGuard: auth-gurad.service.ts
import { Injectable } from '@angular/core';
import {
CanActivate, Router,
ActivatedRouteSnapshot,
RouterStateSnapshot,
CanActivateChild,
NavigationExtras,
CanLoad, Route
} from '@angular/router';
import { AuthService } from './auth.service';
@Injectable()
export class AuthGuard implements CanActivate, CanActivateChild, CanLoad {
constructor(private authService: AuthService, private router: Router) { }
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
let url: string = state.url;
return this.checkLogin(url);
}
canActivateChild(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
return this.canActivate(route, state);
}
canLoad(route: Route): boolean {
let url = `/${route.path}`; // here i got url path 'assignment' instead 'assignment/3/detail'
return this.checkLogin(url);
}
checkLogin(url: string): boolean {
if (this.authService.isLoggedIn) {
if(this.authService.redirectUrl!=null){
let redirectUrl = this.authService.redirectUrl;
this.authService.redirectUrl = null;
this.this.router.navigate([redirectUrl]);
}
return true;
}
// Store the attempted URL for redirecting
this.authService.redirectUrl = url;
// Navigate to the login page
this.router.navigate(['/login']);
return false;
}
}
I have this exact same problem. These issues are related
And they even have an open PR about this which hasn't been merged yet
The workaround for now seems to be to replace the canLoad
method with the canActivate
, there you can have access to the full path, the bad thing of course is that you're loading the module
Edit: Also for you Assignment routing, there's no need to call canActivate
for each child route. Have it defined on the parent route should apply the guard for all child routes.
There is another temporary workaround instead of replacing canLoad
with canActivate
:
You can store the url via redirectUrl = location.pathname
and redirect later via this.router.navigateByUrl(redirectUrl);
. Of course, if you work on a subpath (like domain
) you have to adjust the pathname
a little bit.