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();
            }
        );
    }
    // =====================================================
}
      

Run code



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('/');
    }
    // =====================================================
}
      

Run code



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(); }
}
      

Run code



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();
    }
    // =====================================================
}
      

Run code


Any suggestion please?

+3


source to share


1 answer


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!

+1


source







All Articles