Search code examples
javascripthtmlangularserviceangular-ng-if

Automatically refresh navbar when service data changes


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?


Solution

  • 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>