Dave V
Dave V

Reputation: 1976

Angular 2 RC4 Route Guards service injection

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

Answers (1)

Dave V
Dave V

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

Related Questions