How to hide header component on login page in Angular 4?

pranay anand picture pranay anand · Dec 21, 2017 · Viewed 17k times · Source

I am very new to angular 4 and angular material and i am still at learning phase. I am trying to create an app where user logs in and navigates to dashboard. Now i am showing a header component in dashboard and hiding it in login page. But when i refresh the browser on dashboard the header component doesnt loads. I used This Tutorial to create the PoC

Now i am not able to figure out the solution.Any help would be appreciated. Thanks in Advance...!!!

Please find my code below

app.module.ts

    import { BrowserModule } from '@angular/platform-browser';
    import { NgModule } from '@angular/core';
    import { HttpClientModule, HttpClient } from '@angular/common/http';
    import { HttpModule } from '@angular/http';
    import { RouterModule, Routes } from '@angular/router';
    import 'hammerjs';
    import { NgxPhoneSelectModule } from 'ngx-phone-select';
    import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
    import { FormsModule, ReactiveFormsModule } from '@angular/forms';
    import { MatInputModule, MatButtonModule, MatSelectModule } from '@angular/material';
    import { MatGridListModule } from '@angular/material';
    import { MatTableModule } from '@angular/material';
    import { MaterialModule } from './modules/material/material.module';


    import { AppComponent } from './app.component';
    import { CustomerComponent } from './components/customer/customer.component';
    import { LoginComponent } from './components/login/login.component';
    import { ForgetPasswordComponent } from './components/forget-password/forget-password.component';
    import { PageNotFoundComponent } from './components/page-not-found/page-not-found.component';
    import { DashboardComponent } from './components/dashboard/dashboard.component';

    import { FleetDataService } from './services/fleet-data.service';
    import { LoaderService } from './services/loader.service';
    import { HeaderComponent } from './components/header/header.component';
    import { AuthService } from './services/auth.service';
    import { AuthGuard } from './services/auth.guard';
    const appRoutes: Routes = [
      {
        path: '',
        component: LoginComponent
      },
      {
        path: 'create-customer',
        component: CustomerComponent,
        //        canActivate: [AuthGuard] // ristrict direct access of links
      },
      {
        path: 'forget-password',
        component: ForgetPasswordComponent,
        //        canActivate: [AuthGuard] // ristrict direct access of links
      },
      {
        path: 'dashboard',
        component: DashboardComponent,
                  canActivate: [AuthGuard] // ristrict direct access of links
      },
      {
        path: '**',
        component: PageNotFoundComponent
      }
    ];

    @NgModule({
      declarations: [
        AppComponent,
        CustomerComponent,
        LoginComponent,
        ForgetPasswordComponent,
        PageNotFoundComponent,
        DashboardComponent,
        HeaderComponent
      ],
      imports: [
        BrowserModule,
        HttpClientModule,
        HttpModule,
        RouterModule.forRoot(appRoutes),
        NgxPhoneSelectModule,
        BrowserAnimationsModule,
        FormsModule,
        ReactiveFormsModule,
        MatInputModule,
        MatButtonModule,
        MatSelectModule,
        MatGridListModule,
        MatTableModule,
        MaterialModule
      ],
      providers: [FleetDataService, LoaderService, AuthService, AuthGuard],
      bootstrap: [AppComponent]
    })
    export class AppModule { }

app.component.ts

    import { Component } from '@angular/core';

    @Component({
      selector: 'app-root',
      templateUrl: './app.component.html',
      styleUrls: ['./app.component.scss']
    })
    export class AppComponent {
      title = 'app';
    }

app.component.html

    <div id="fullPage">
      <app-header ></app-header>
      <router-outlet></router-outlet>
    </div>

login.component.html

    <div class="fstBg container-fluid">
      <div class="row">
      <div class="col-md-12 logo pull-right"></div>
        <div class="col-md-4">&nbsp;</div>
        <div class="col-md-4">
          <form [formGroup]="form" (ngSubmit)="onSubmit()">
            <div class="example-container">
              <mat-input-container>
                <input matInput placeholder="Username" formControlName="userName" required>
                <mat-error *ngIf="isFieldInvalid('userName')">
                  User name cannot be empty
                </mat-error>
              </mat-input-container>
              <mat-input-container>
                <input matInput type="password" placeholder="Password" formControlName="password" required>
                <mat-icon matSuffix (click)="hide = !hide" ngClass="{{hide ? 'glyphicon glyphicon-eye-open' : 'glyphicon glyphicon-eye-close'}}"></mat-icon>
                <mat-error *ngIf="isFieldInvalid('userName')">
                  Password cannot be empty
                </mat-error>
              </mat-input-container>
              <br /><br />
              <button type="submit" class="btn col-md-12  orange_btn" mat-raised-button>Login</button>

              <div class="bottom-div col-md-12 text-right pd0">       
                <a id="button_right" routerLink="forget-password" class="white_text hover_link link">Forget Password</a>
              </div>
              <br><br>
            </div>
          </form>
          </div>
        <div class="col-md-4">&nbsp;</div>
        </div>
    </div>

login.component.ts

    import { Component, OnInit } from '@angular/core';
    import { FormGroup, FormBuilder, Validators } from '@angular/forms';
    // import { Router } from '@angular/router';
    // import { User } from '../../models/login.interface';
    import { AuthService } from '../../services/auth.service';

    @Component({
      selector: 'app-login',
      templateUrl: './login.component.html',
      styleUrls: ['./login.component.scss']
    })
    export class LoginComponent implements OnInit {
      form: FormGroup;
      private formSubmitAttempt: boolean;
      constructor(private fb: FormBuilder,
        private authService: AuthService) {}
      ngOnInit() {
        this.form = this.fb.group({     // {5}
          userName: ['', Validators.required],
          password: ['', Validators.required]
        });
      }
      isFieldInvalid(field: string) {  // {6}
        return (
          (!this.form.get(field).valid && this.form.get(field).touched) ||
          (this.form.get(field).untouched && this.formSubmitAttempt)
        );
      }
      onSubmit() {
        if (this.form.valid) {
          this.authService.login(this.form.value); // {7}
        }
        this.formSubmitAttempt = true;
      }
    }

header.component.html

    <div class="row mrg0 hidden-xs" *ngIf="isLoggedIn$ | async as isLoggedIn">
      <div class="col-md-8 col-lg-8 col-sm-8">
        <div class="logo_div">
          <div class="logo" routerLink="user-management"></div>
        </div>
      </div>
      <div class="col-md-4 col-lg-4 col-sm-4 right_panel">
        <div class="row mrg0">
          <div class="col-md-6 col-lg-8 col-sm-6 text-right pd0 user_name"><i class="material-icons gray_icon user_name">person</i> <span>Hello Admin</span></div>    
          <div class="col-md-4 col-lg-4 col-sm-4 logout link" (click)="onLogout()" *ngIf="isLoggedIn"><a><i class="material-icons gray_icon clickable" matTooltip="Logout">exit_to_app</i>&nbsp;<span>Logout</span></a></div>
        </div>
      </div>
    </div>

header.component.ts

    import { Component, OnInit } from '@angular/core';
    import { Observable } from 'rxjs/Observable';
    import { AuthService } from '../../services/auth.service';
    @Component({
      selector: 'app-header',
      templateUrl: './header.component.html',
      styleUrls: ['./header.component.scss']
    })
    export class HeaderComponent implements OnInit {
      isLoggedIn$: Observable<boolean>;
      constructor(private authService: AuthService) { }

      ngOnInit() {
        this.isLoggedIn$ = this.authService.isLoggedIn; // {2}
      }
      onLogout() {
        this.authService.logout();                      // {3}
      }

    }

dashboard.component.ts

import { Component } from '@angular/core';

@Component({
  selector: 'app-dashboard',
  template: '<p>Yay! You are logged in!</p>',
  styles: []
})
export class DashBoardComponent {}

auth.guard

    import { Injectable } from '@angular/core';
    import {
      CanActivate,
      ActivatedRouteSnapshot,
      RouterStateSnapshot,
      Router
    } from '@angular/router';
    import { AuthService } from './auth.service';
    import { Observable } from 'rxjs/Observable';
    import 'rxjs/add/operator/take';
    import 'rxjs/add/operator/map';

    @Injectable()
    export class AuthGuard implements CanActivate {
      constructor(
        private authService: AuthService,
        private router: Router
      ) {}

      canActivate(
        next: ActivatedRouteSnapshot,
        state: RouterStateSnapshot
      ): Observable<boolean> {
        return this.authService.isLoggedIn       // {1}
          .take(1)                               // {2}
          .map((isLoggedIn: boolean) => {        // {3}
            if (!isLoggedIn) {
              this.router.navigate(['']);  // {4}
              return false;
            }
            return true;
          });
      }
    }

auth.service

    import { Injectable } from '@angular/core';
    import { Router } from '@angular/router';
    import { BehaviorSubject } from 'rxjs/BehaviorSubject';
    import { User } from '../models/login.interface';

    @Injectable()
    export class AuthService {
      private loggedIn = new BehaviorSubject<boolean>(false); // {1}

      get isLoggedIn() {
        return this.loggedIn.asObservable(); // {2}
      }

      constructor(
        private router: Router
      ) {}

      login(user: User) {
        if (user.userName !== '' && user.password !== '' ) { // {3}
          this.loggedIn.next(true);
          this.router.navigate(['/dashboard']);
        }
      }

      logout() {                            // {4}
        this.loggedIn.next(false);
        this.router.navigate(['']);
      }
    }

login.interface.ts

   export interface User {
   userName: string;
   password: string;
  }

Answer

Mr. Wizard picture Mr. Wizard · Aug 29, 2018

I know I'm late, but maybe, sometime, this will help somebody. I have developed this solution and it's working

In app.component.ts have something like this:

import { Component } from '@angular/core';
import { Router, NavigationStart } from '@angular/router';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'app';

  showHead: boolean = false;

  ngOnInit() {
  }

  constructor(private router: Router) {
  // on route change to '/login', set the variable showHead to false
    router.events.forEach((event) => {
      if (event instanceof NavigationStart) {
        if (event['url'] == '/login') {
          this.showHead = false;
        } else {
          // console.log("NU")
          this.showHead = true;
        }
      }
    });
  }
}

In app.component.html

<app-header *ngIf="showHead"></app-header>
<router-outlet></router-outlet>

If you don't know about NavigationStart, go console.log(event) and see more info that are pretty helpful.