Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular 2 redirect if user is logged in

I have routes like this:

const routes: Routes = [
  { path: '', redirectTo: '/login', pathMatch: 'full' },
  { path: 'login', component: LoginComponent },
  { path: 'dashboard', component: DashboardComponent, canActivate: [AuthGuard] },
];

and AuthGuard:

export class AuthGuard implements CanActivate, CanActivateChild {
  constructor(private router: Router,
              private authService: AuthService) { }

  canActivate() {
    if (this.authService.isLoggedIn()) {
      return true;
    }
    this.router.navigate(['login']);
    return false;
  }
}

When the user visits the website, he gets redirected to the login page. Same happens when the user tries to access /dashboard route without authentication. How can I redirect the user to /dashboard if he's logged in? For example, when I visit myapp.com and I'm logged in I want to be redirected to myapp.com/dashboard.

like image 344
Ihor Tkachuk Avatar asked May 22 '17 19:05

Ihor Tkachuk


1 Answers

You want to look at the resolve property within the [Route interface].

All of the following properties are available to a route:

export interface Route {
  path?: string;
  pathMatch?: string;
  matcher?: UrlMatcher;
  component?: Type<any>;
  redirectTo?: string;
  outlet?: string;
  canActivate?: any[];
  canActivateChild?: any[];
  canDeactivate?: any[];
  canLoad?: any[];
  data?: Data;
  resolve?: ResolveData;
  children?: Routes;
  loadChildren?: LoadChildren;
  runGuardsAndResolvers?: RunGuardsAndResolvers;
  _loadedConfig?: LoadedRouterConfig;
}

resolve is designed to allow you to load some type of data before proceeding to the route. The signature for resolve looks like this:

resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) : Observable<T>|Promise<T>|T

We can ignore that signature, however, and override it because, in this case, we want to redirect to /dashboard if the user is logged in. Otherwise, display /login route normally.

The solution is to create an injectable class and attach it to the login route's resolve property.

@Injectable()
export class IsLoggedIn {
  constructor(
    private router: Router, 
    private authService: AuthService) {
  }

  resolve(): void {
    if (this.authService.isAuthenticated) this.router.navigate(['/dashboard'])
  }
}

On your /login route, add the resolve property.

{
  path: 'login',
  component: LoginComponent,
  resolve: [IsLoggedIn]
}

Import the class in AppModule and add it to providers.

providers: [
  IsLoggedIn
]

Now anytime a logged in user attempts to go to /login, they'll be redirected to /dashboard without seeing the login page.

like image 183
MrPizzaFace Avatar answered Oct 13 '22 11:10

MrPizzaFace