In my Navbar component, I am attempting to determine whether the user is logged in or not so that I can enable/disable certain Navbar items. I have implemented a BehaviorSubject to multicast the data. The AuthenticationService class contains the BehaviorSubject object, as shown in the code snippet below:
import {Injectable} from '@angular/core';
import {Http, RequestOptions, Headers} from '@angular/http';
import {LocalStorage, SessionStorage} from "angular2-localstorage/WebStorage";
import {BehaviorSubject} from 'rxjs/BehaviorSubject';
import {Credentials} from './credentials';
@Injectable()
export class AuthenticationService {
private _baseUrl="http://localhost:8080/webapi/authenticate/";
private loggedIn: boolean;
// Observable UserLoggedIn source
private _userLoggedInBehavior = new BehaviorSubject<boolean>(false);
// Observable UserLoggedIn stream
userLoggedInBehaviorStream = this._userLoggedInBehavior.asObservable();
constructor(private _http: Http){
this.loggedIn = localStorage.getItem("authToken");
}
authenticate(credentials: Credentials){
return this._http.post(
this._baseUrl
, JSON.stringify(credentials)
, this.getOptions()
)
.map(res => res.json())
.map((res) => {
if (res.success) {
sessionStorage.setItem("authToken", res.data.token);
this.loggedIn = true;
}
return res.success;
});
}
logout() {
sessionStorage.removeItem("authToken");
this.loggedIn = false;
}
isLoggedIn() {
return this.loggedIn;
}
changeUserLoggedInBehavior(loggedIn) {
this._userLoggedInBehavior.next(loggedIn);
}
getOptions(){
var jsonHeader = new Headers({
'Content-Type':'application/json'
});
var options = new RequestOptions({
headers: jsonHeader
});
return options;
}
}
The AuthenticationComponent triggers the authentication process, and its code looks like this:
import {Component, OnInit, EventEmitter} from '@angular/core';
import {CanDeactivate, Router} from '@angular/router-deprecated';
import {ControlGroup, Control, Validators, FormBuilder} from '@angular/common';
import {AuthenticationService} from './authentication.service';
import {Credentials} from './credentials';
import {EmailValidator} from '../../validators/email-validator';
@Component({
selector:'auth'
, templateUrl:'app/components/authentication/authentication.component.html'
, providers:[AuthenticationService]
})
export class AuthenticationComponent{
form: ControlGroup;
title: string = "LogIn";
credentials: Credentials = new Credentials();
constructor(
fb: FormBuilder
, private _authService: AuthenticationService
, private _router: Router){
this.form = fb.group({
emailId:[
''
, Validators.compose(
[
Validators.required
, EmailValidator.mustBeValidEmail
]
)
]
,password:[
''
, Validators.compose(
[
Validators.required
]
)
]
});
}
save(){
this._authService.authenticate (this.credentials)
.subscribe((result) => {
if (result) {
this._authService.changeUserLoggedInBehavior(true);
this._router.navigate(['Home']);
}
});
}
}
Lastly, the NavbarComponent code is as follows:
import {Component, OnInit, OnDestroy} from '@angular/core';
import {RouterLink} from '@angular/router-deprecated';
import {Subscription} from 'rxjs/Subscription';
import {AuthenticationService} from '../components/authentication/authentication.service';
@Component({
selector:'navbar'
, templateUrl: 'app/navbar/navbar.component.html'
, directives:[RouterLink]
, providers:[AuthenticationService]
})
export class NavbarComponent implements OnInit, OnDestroy{
private _isUserLoggedIn: boolean=false;
subscription: Subscription;
constructor(
private _authService: AuthenticationService
){}
ngOnInit(){
this.subscription = this._authService.userLoggedInBehaviorStream
.subscribe(
loggedIn => this._isUserLoggedIn = loggedIn
);
}
ngOnDestroy(){
// prevent memory leak when component is destroyed
this.subscription.unsubscribe();
}
public setUserLoggedId(isLoggedIn: boolean){
this._isUserLoggedIn = isLoggedIn;
}
}
I referred to an example on Stack Overflow to write this code (source). Please let me know if you see any issues with it.