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"> </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"> </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> <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;
}
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.