1

I am working on an application where I have defined numerous tabs on the navbar. Some of them are hidden. I have a login tab where after the user logs in I want to make it disappear and display the log out tab. I have correctly made my logic but, I am having an issue. All those tabs are routes whereas navbar component isn't. It only gets rendered one time as I start the application. I have used service in my login component and passing that data to my navbar component but, despite after the user logs in, the navbar isn't updating with new tab (log out) on its own. I have to let's say click on a button to call the ngOnInit() method of navbar component again. Here's my code:

navbar.component.html

<div class="collapse navbar-collapse" id="navbarSupportedContent" >
<ul class="navbar-nav ml-auto">
  <li class="nav-item" routerLinkActive = "active" [routerLinkActiveOptions] = "{exact: true}">
    <a class="nav-link" routerLink = "/">Home</a>
  </li>
  <li class="nav-item" routerLinkActive = "active">
    <a class="nav-link" routerLink = "/findcourse">Find Courses</a>
  </li>
  <li class="nav-item" routerLinkActive = "active">
    <a class="nav-link" routerLink = "/feedback">Feedback</a>
  </li>
  <li class="nav-item" routerLinkActive = "active">
    <a class="nav-link" routerLink = "/register">Register</a>
  </li>
  <li class="nav-item" routerLinkActive = "active" *ngIf = "loggedIn">
    <a class="nav-link" routerLink = "/login">Login</a>
  </li>
  <li class="nav-item" routerLinkActive = "active" *ngIf = "loggedOut">
    <a class="nav-link" routerLink = "/logout">Log out</a>
  </li>
  <button type="button" name="button" class = "btn btn-outline-info" (click) = "ngOnInit()">Check</button>
</ul>
</div>

navbar.component.ts

ngOnInit(): void         //I want to call this on its own not only at the time of rendering but every time user logs in
{
if(this.login.isAuthenticated() == true)
{
  this.loggedOut = true;
  this.loggedIn = false;
}
else if(this.login.isAuthenticated() == false)
{
  this.loggedOut = false;
  this.loggedIn = true;
}
}

login.component.ts

logIn(form: NgForm)
{
 this.http.post('http://localhost:3000/login', form.value, {responseType: "text"})
 .subscribe(responseData => {
  if(responseData == 'Successfully logged in')
  {
    this.logInSuccess = true;
    this.showlogInAlert();
    this.auth.checkAuthentication(true);
  }
  else if(responseData == 'User login failed')
  {
    this.logInFailure = true;
    this.auth.checkAuthentication(false);
  }
 }
,error =>{
this.serverError = true;
this.showserverAlert();
});

form.reset();
}

login.service.ts

 export class Login
{
 logInSuccess: boolean = false;

 checkAuthentication(check : boolean)
{
 if(check === true)
 {
  this.logInSuccess = true;
 }
 else
 {
  this.logInSuccess = false;
 }
}

isAuthenticated()
{
 return this.logInSuccess;
}
}

How can I re-render the navbar on its own? I don't know how to do that? Is there a way to make Angular to check for change detection in navbar on its own?

Package.JSON
  • 157
  • 12

1 Answers1

2

Quick way to fix would be to use the login service isAuthenticated value directly in your html:

  <li class="nav-item" routerLinkActive = "active" *ngIf = "!login.isAuthenticated()">
    <a class="nav-link" routerLink = "/login">Login</a>
  </li>
  <li class="nav-item" routerLinkActive = "active" *ngIf = "login.isAuthenticated()">
    <a class="nav-link" routerLink = "/logout">Log out</a>
  </li>

It will get the latest value from the service as it is updated.

More efficient in terms of change detection would be to expose the value as an observable and subscribe to changes in your component. Example in answer to this question.

JMP
  • 1,561
  • 2
  • 4
  • 12