Show registration / login links for guests, hide on login?
I have a navigation bar with three items register
, login
and logout
.
I am trying to update the visibility of navigation items when the user logs in / out.
I am using a notification service to notify my TopNav component to update a named variable loggedIn
which in turn shows / hides these items above
The problem is this: Notification service is not sending notification to TopNavComponent!
I've debugged my code, sometimes the observer array is loginStatusChanged$
empty, which shouldn't happen since I have to subscribe to the notification!
TopNavComponent.ts
import { NotificationService } from 'app/includes/services/notification.service';
import { AuthenticationService } from 'app/includes/services/auth-services/authentication.service';
@Component({
selector : 'app-topnav',
template : `
<a [routerLink]="['/register']" *ngIf="!loggedIn">Register</a>
<a [routerLink]="['/login']" *ngIf="!loggedIn">Login</a>
<app-loggedin-menu remove-host *ngIf="loggedIn"></app-loggedin-menu>`,
providers : [Auth, NotificationService, AuthenticationService]
})
export class TopNavComponent implements OnInit
{
subscription : Subscription;
loggedIn = this.auth.loggedIn();
constructor(private auth: Auth, private authService: AuthenticationService, private router: Router, private notifService: NotificationService) { }
// =====================================================
ngOnInit()
{
// Listen to login change notifications & act accordingly
this.subscription = this.notifService.loginStatusChanged$.subscribe(
() => {
// Update login status
this.loggedIn = this.auth.loggedIn();
}
);
}
// =====================================================
}
Loggedin menu component
import { AuthenticationService } from 'app/includes/services/auth-services/authentication.service';
@Component({
selector : 'app-loggedin-menu',
template : `<a (click)="logOut()">Log Out</a>`,
encapsulation: ViewEncapsulation.None,
providers : [AuthenticationService],
})
export class LoggedinMenuComponent
{
// =====================================================
constructor(private authService: AuthenticationService, private router: Router) { }
// =====================================================
logOut()
{
this.authService.logout();
// logout successful, redirect to home page
this.router.navigateByUrl('/');
}
// =====================================================
}
Notification service
import { Injectable } from '@angular/core';
import { Subject } from 'rxjs/Subject';
@Injectable()
export class NotificationService
{
// Observable string sources
private loginChangedSource = new Subject<boolean>();
// Observable string streams
loginStatusChanged$ = this.loginChangedSource.asObservable();
// Service message commands
updateLogin() { this.loginChangedSource.next(); }
}
Authentication service
@Injectable()
export class AuthenticationService
{
public token: string;
constructor(private http: Http, private notifService: NotificationService) { }
// =====================================================
login(user: ILoginModel)
{
return this.http.post(this.appURL + 'api/account/login/', user)
.map((response: Response) =>
{
// login successful if there a jwt token in the response
const token = response.json() && response.json().token;
if (token)
{
// set token property
this.token = token;
// store username and jwt token in local storage to keep user logged in between page refreshes
localStorage.setItem('access_token', JSON.stringify({ username: user.UserName, token: token }));
// Notify other components to change top-right nav info accordingly
this.notifService.updateLogin();
// return true to indicate successful login
return '';
} else
{
// return false to indicate failed login
return response.text();
}
})
.catch(this.handleError);
}
// =====================================================
logout()
{
// Clear token & remove user from local storage to log user out
this.token = null;
localStorage.removeItem(consts.tokenName);
// Notify other components to change top-right nav info accordingly
this.notifService.updateLogin();
}
// =====================================================
}
Any suggestion please?
source to share
Oh my God! I spent 2 days trying to debug this thing, and literally 2 minutes after posting my question; I realized that I need to remove NotificationService
from the supplier list inTopNavComponent .ts
Suppliers: [Auth, NotificationService , AuthenticationService]
Just in case someone runs into this problem!
source to share