I'm trying to make a login-logout navbar, which only shows the logout button when there is a user logged in, and only shows the Login button when there isn't any user logged in. I'm using firebase auth service and one of its functions detects whether there is a user logged in or not. I'm achieving this by putting an *ngIf on each button I want it to check, like this:
<a *ngIf="!_auth.userData" routerLink="/auth/login" class="login active">Login</a>
<a *ngIf="!_auth.userData" routerLink="/auth/register" class="register active">Register</a>
<a *ngIf="_auth.userData" routerLink="/landing" class="landing active">Landing</a>
<div class="divider anchor active">|</div>
<li class="profile anchor active">Profile</li>
<li class="paginator anchor active">Paginator</li>
<li class="search anchor active">Search</li>
<li class="ng-content anchor active">NgContent</li>
<li class="footer anchor active">Footer</li>
<div class="divider anchor active">|</div>
<a *ngIf="_auth.userData" (click)="_auth.SignOut()" class="logout active">Logout</a>
<a *ngIf="!_auth.userData" routerLink="/auth/forgot" class="forgot active">Forgot Password</a>
The actual login is inside the login component and has the next code:
<button [disabled]="loginForm.invalid" class="button" type="submit" (click)="_auth.SignIn(userEmail.value, userPassword.value)">Login</button>
The *ngIf detects the state of _auth.userData, this function returns null when no user is logged in.
/* Saving user data in localstorage when
logged in and setting up null when logged out */
this._afAuth.authState.subscribe(user => {
if (user) {
this.userData = user;
localStorage.setItem('user', JSON.stringify(this.userData));
JSON.parse(localStorage.getItem('user')!);
} else {
localStorage.setItem('user', "");
JSON.parse(localStorage.getItem('user')!);
}
})
}
It works fine, but I have to refresh the page manually every time a login or logout in order for the navbar to refresh. How can I make it automatically refresh when the user logs in or logs out?
So your userData holds the current user value, and you cannot detect that change in your template. What I would do is:
// assuming it's an auth service, I'd do something like this: set the value of the login state in your public service property based on the localstorage value
isLoggedIn$ = new BehaviorSubject(!!localStorage.getItem('user'));
// service call when logging in - change the state of the isLoggedIn$
this._afAuth.authState.subscribe(user => {
if (user) {
this.userData = user;
localStorage.setItem('user', JSON.stringify(this.userData));
JSON.parse(localStorage.getItem('user') || "{}");
this.isLoggedIn$.next(true);
} else {
localStorage.removeItem('user');
JSON.parse(localStorage.getItem('user') || "{}");
this.isLoggedIn$.next(false);
}
})
// and in the template file
<a *ngIf="!(_auth.isLoggedIn$ | async)" routerLink="/auth/login" class="login active">Login</a>
<a *ngIf="_auth.isLoggedIn$ | async" routerLink="/auth/register" class="login active">register</a>