Reputation: 1976
I'm having an issue with the Route Guards in Angular 2. It seems like the Guard is getting a separate instance of my authentication service.
I'm attempting to setup my guard similarly to the Angular documentation:
The Guard:
@Injectable()
export class AuthenticationGuard implements CanActivate {
constructor(private router:Router,
private authenticationService:AuthenticationService) {
}
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
if (this.authenticationService.isLoggedIn) {
return true;
}
this.router.navigate(['/login']);
return false;
}
}
The Service:
@Injectable()
export class AuthenticationService {
isLoggedIn:boolean = false;
login() {
return Observable.of(true).delay(1000).do(val => this.isLoggedIn = true);
}
logout() {
this.isLoggedIn = false;
}
}
The Login:
export class LoginComponent {
constructor(private router:Router,
private authenticationService:AuthenticationService) {
}
login() {
//TODO: Flesh out actual authentication
this.authenticationService.login()
.subscribe(() => {
if (this.authenticationService.isLoggedIn) {
this.router.navigate(["/dashboard"]);
}
});
}
The Bootstrap:
import {bootstrap} from "@angular/platform-browser-dynamic";
import {RouterConfig, provideRouter} from "@angular/router";
import {HTTP_PROVIDERS} from "@angular/http";
//Components
import {MainComponent} from "./main/main.component";
//Routes
import {LoginRoutes, AUTHENTICATION_PROVIDERS} from "./routes/login.routes";
import {DashboardRoutes} from "./routes/dashboard.routes";
import {AdministrationRoutes} from "./routes/administration.routes";
const routes: RouterConfig = [
...LoginRoutes,
...DashboardRoutes,
...AdministrationRoutes
];
//Providers
const ROUTE_PROVIDER = [
provideRouter(routes),
AUTHENTICATION_PROVIDERS
];
bootstrap(MainComponent, [
HTTP_PROVIDERS,
ROUTE_PROVIDER
]);
The Login Routes:
import {RouterConfig} from "@angular/router";
import {AuthenticationGuard} from "../guards/authentication.guard";
import {AuthenticationService} from "../services/authentication.service";
import {LoginComponent} from "../login/login.component";
export const LoginRoutes: RouterConfig = [
{path: "", redirectTo: "/login", pathMatch: "full"},
{path: "login", component: LoginComponent}
];
export const AUTHENTICATION_PROVIDERS = [
AuthenticationGuard, AuthenticationService
];
In the LoginComponent
's login()
, the authenticationSerivce.isLoggedIn
is true
. However, when the redirect to the Dashboard happens, the Guard is triggered, and inside it, the authenticationService.isLoggedIn
is false
.
I'm sure I'm just missing something in the dependency injection, but I can't figure it out nor see any difference in what I'm actually doing vs. the tutorial/documentation stuff.
Upvotes: 3
Views: 987
Reputation: 1976
Holy crap, I just got it. Declaring the Authentication Service as a provider in my MainComponent
was creating a separate instance of the service since I had already declared it a provider in the bootstrap
. I took out the providers reference to it in the MainComponent
and everything is working now!!
Upvotes: 5