1

I have a header with a few buttons such as Home, About us, Register, Log in, Log out, Register and I want to show all except Log in and Register when user is logged in and only those two if user isn't logged.

I know that I can use something like this:

<li *ngIf="!isUserLoggedIn"><a href="#">Log in</a></li>
<li *ngIf="isUserLoggedIn"><a href="#">Log out</a></li>
<li *ngIf="!isUserLoggedIn"><a href="#">Register</a></li>

but it's probably a bad idea to call a service from a header to check whether user is logged and initialize this variable. Am I right ?

6
  • Why would it be a bad idea? Commented Aug 29, 2016 at 20:34
  • I thought that it isn't a header responsibility to check that, but I am a beginner, so maybe I misunderstood something Commented Aug 29, 2016 at 20:37
  • It's not the header's responsibility to implement the verification. But since it just delegates to a service to know if the user is logged in and allow its view to act accordingly, there's no problem. Commented Aug 29, 2016 at 20:45
  • Okey, but there is one more problem with that solution. I can assign this variable in constructor, but it should change dynamically when the user clicks log in or log out Commented Aug 29, 2016 at 20:46
  • 1
    You should not call the service in the constructor, but in ngOnInit(). When the user logs in or out, make the service emit an event from an Observable that the components can subscribe to. Commented Aug 29, 2016 at 20:48

1 Answer 1

1

What I did was:

1 - Create an Auth Service that is responsable for set a variable that represents the auth status.

2 - Set the auth status variable to an Observation one;

3 - On the header component you can subscribe to this auth service variable observer and then change the header mode based on the auth variable status.

For example:

auth.service.ts

Ps. Notice the localStorage.getItem('authState') when declaring the authStateSubject. This way you can get the current state of the user.

...
@Injectable()
export class AuthService {

  // you can get the actual state from memory here
  private authStateSubject: BehaviorSubject<Boolean> = new BehaviorSubject<Boolean>(localStorage.getItem('authState'));

  state: Observable<Boolean> = this.authStateSubject.asObservable();
...

header.component.ts

...
@Component({
  ...
})

export class SidenavLeftComponent {

  isUserLoggedIn: boolean;

  constructor(private authService: AuthService) {
    ...
  }

  ngOnInit(){
    // update auth status when it changes
    this.authService.state.subscribe(state => this.isUserLoggedIn = state);
  }

}
...

header.component.html

...
<li *ngIf="!isUserLoggedIn"><a href="#">Log in</a></li>
<li *ngIf="isUserLoggedIn"><a href="#">Log out</a></li>
<li *ngIf="!isUserLoggedIn"><a href="#">Register</a></li>
...

When the user logs in, you call this method in the auth.service.ts this.authStateSubject.next(true);

When the user logs out, you call this method in the auth.service.ts this.authStateSubject.next(false);

That way, all subscribers will notice the new value and act over it.

Sign up to request clarification or add additional context in comments.

3 Comments

I've just notice that it doesn't work when I refresh browser. State is lost and I am logged in, but buttons Log in and register are visible and Log out not
It is because you need to save the state in your localStorage or sessionStorage. If you don't, when you refresh the browser, all data is lost. What I did was only show you how to subscribe to the service variable not how to store the data locally. If you need help on this, maybe this can help you: w3schools.com/html/html5_webstorage.asp
I edited my answer to get the local Storage authState when declaring the auth.servic.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.