Mace
Mace

Reputation: 1089

How do I selectively hide a navigation bar using Angular?

We want to hide the login bar on the login page. The value in the template never changes, and the only page we want to hide the navigation is on the login-page.

The service that is called when the navigation bar should get enabled or disabled. isAuthenticated.service:

import {Injectable} from '@angular/core';
import {Observable}     from 'rxjs/Observable';

@Injectable()
export class isAuthenticatedService{

userLoggedIn : boolean = false;

//call this function when login status changes
changeLoginStatus(status: boolean){
    this.userLoggedIn = status;
    console.log("in changeLoginStatus: ", status);
}

getLoginStatus(){
    return this.userLoggedIn;
}
}

app.component:

import {Component} from '@angular/core';
import {ProfilComponent} from './profil.component';
import {EditProfilComponent} from './editProfil.component';
import { HTTPService } from './http.service';
import {CookieService} from 'angular2-cookie/services/cookies.service';
import {Router} from '@angular/router';
import {isAuthenticatedService} from './isAuthenticated.service'

@Component({
selector: 'my-app',
templateUrl: './app/main.html',
providers: [HTTPService, CookieService, isAuthenticatedService]
})
export class AppComponent{
constructor(private _httpService: HTTPService, private _cookieService: CookieService, public router: Router, private _isAuthenticatedService: isAuthenticatedService){
    console.log(this.router.url);
}
};

Template that is used in app.component to display the navigation.

main.html:

<div [hidden]="_isAuthenticatedService.userLoggedIn">
<nav class="navbar navbar-inverse">
<div class="container-fluid">
<div class="collapse navbar-collapse">
  <ul class="nav navbar-nav">
    <li><a routerLink="/mainpage">Portal |</a></li>
   <li><a routerLink="/profil">Profil</a></li>
    <li><a href="/">Unternehmen</a></li>
  </ul>
  <ul class="nav navbar-nav navbar-right">
 <div class="dropdown" style="float:right;">
<button class="dropdown-toggle btn btn-primary" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false" id ="profildd">Profil <span class="caret"></span></button>
    <ul class="dropdown-menu">
    <li><a routerLink="/profil" routerLinkActive="active">Verwalten</a></li>
    <li role="separator" class="divider"></li>
    <li><a routerLink="/download" routerLinkActive="active">Organisation</a></li>
    <li role="separator" class="divider"></li>
    <li><a routerLink="/" (click)="logout()">Logout</a></li>
    </ul> 
</div>
</ul>
</div>
</div>

The function 'changeLoginStatus(boolean)' is called from the login component if the login was successfull.

Edit 1: Changed Providers

moved providers from app.component to app.module.ts

app.module.ts:

@NgModule({
imports: [ 
BrowserModule,
HttpModule,
FormsModule,
RouterModule.forRoot([
  {path : '', component: LoginComponent},
  {path: 'mainpage', component: MainPageComponent},
  {path: 'profil', component: ProfilComponent},
  {path: 'editProfil', component: EditProfilComponent},
  {path: 'login', component: LoginComponent}
])

],

 declarations: [ AppComponent, ProfilComponent, EditProfilComponent, LoginComponent, MainPageComponent],
 providers : [
{       provide: XSRFStrategy,
        useValue: new CookieXSRFStrategy('XSRF-Token', 'XSRF-TOKEN')
}, isAuthenticatedService, CookieService, HTTPService],
bootstrap:    [ AppComponent ]

})
export class AppModule { }

Upvotes: 0

Views: 4206

Answers (2)

Chris J
Chris J

Reputation: 635

Just wondering why such complicated solutions here? You just need something that checks whether the user is logged in in your Navigation Component like this:

Navmenu.component.ts:

import { Component } from '@angular/core';
import {Location, LocationStrategy, PathLocationStrategy} from '@angular/common';
import { AuthService } from '../authguard/auth.service';

@Component({
selector: 'nav-menu',
providers: [Location, { provide: LocationStrategy, useClass: PathLocationStrategy }],
templateUrl: './navmenu.component.html',
styleUrls: ['./navmenu.component.css']})

export class NavMenuComponent {
  constructor(private authService: AuthService) { }
  location: Location;
  isActive() {
  return !this.authService.loggedIn();
  }
...
}

navmenu.component.html:

<div class='main-nav' [hidden]="isActive()">
<div class='navbar navbar-inverse'>
...

Then, in your top menu bar , have a login/logout 'panel':

 <ul class="nav navbar-nav navbar-right">
        <li>
            <a (click)=authService.login() *ngIf="!authService.loggedIn()">Log In</a>
        </li>
        <li>
            <a (click)=authService.logout() *ngIf="authService.loggedIn()">Log Out</a>
        </li>
    </ul>
</nav>
<div class='row'>
    <div class='col-sm-3'>
        <nav-menu></nav-menu>
...

Upvotes: 0

micronyks
micronyks

Reputation: 55443

The problem is

providers: [HTTPService, CookieService, isAuthenticatedService]

This line creates different instance of the service (per component) and so you will not have expected outcome.

you should use singleton service which shares single instance of the service among components where one component changes something in service and other component gets the same update via service

So for that pupose you should declare your service in RootModule's or AppModule's @NgModule decorator as shown below,

@NgModule({
   ...
   providers: [HTTPService, CookieService, isAuthenticatedService]  
   //<<< this will create single instance of services throughout app
  ...
})

AND REMOVE providers:[...] declaration from @Component,

@Component({
    selector: 'my-app',
    templateUrl: './app/main.html',
    providers: [HTTPService, CookieService, isAuthenticatedService] 
    //<<< providers not required here as it creates different instance per component.

})  

EDIT 1:

try this also,

<div [hidden]="_isAuthenticatedService.getLoginStatus()">

Upvotes: 2

Related Questions