Angular 6 Material SideNav Example

author-imageBy Dhiraj, 24 July,2018   12K

In this article, we will be discussing about angular material sidenav and integrate sidenav in an Angular 6 Single Page App along with MatToolBar. We will be creating a collapsible side navigation content on a menu icon click and on the click of the items inside the sidenav, different router components will be loaded in the primary content. To achieve this, we will be using different directives provided by angular material 6 such as <mat-sidenav-container>, <mat-sidenav-content>, <mat-sidenav>.

In my last articles, We have already discussed a lot about creating Angular 5 and Angular 6 app and integrating material design and jwt authentication with it. Hence, I assume you have NPM installed and running and hence let us skip environment setup steps and directly jump into creating the app from CLI command.

Setting Up Angular 6 App

Execute below commands to generate angular 6 app. Make sure you have Node 8.9 or higher, together with NPM 5.5.1 or higher installed in your system.

ng new angular6-sidenav-example
cd angular6-sidenav-example/
ng serve

After executing above commands, you should be now able to access the app on localhost:4200 in the browser.

Once, this is done let us now add material to it. To do so, run below commands:

ng add @angular/material

Now we have material design added to our app, we can import the different modules of it. For a clear implementation, I have created a separate file - material.module.ts and imported in our app.module.ts.

material.module.ts
import {NgModule} from "@angular/core";
import { CommonModule } from '@angular/common';
import {
  MatButtonModule, MatNativeDateModule, MatIconModule, MatSidenavModule, MatListModule, MatToolbarModule} from '@angular/material';

@NgModule({
  imports: [CommonModule, MatButtonModule,MatToolbarModule, MatNativeDateModule, MatIconModule, MatSidenavModule, MatListModule],
  exports: [CommonModule, MatButtonModule, MatToolbarModule, MatNativeDateModule, MatIconModule, MatSidenavModule, MatListModule],
})
export class CustomMaterialModule { }

Below is the complete project structure:

angular6-navbar-project-strct

Sidenav in Angular Material

SideNav basically uses 3 components to add sidenav into a full page. They are - <mat-sidenav-container> which acts as a structural container for content and sidenav, <mat-sidenav-content> which represents the main content, and <mat-sidenav> which represents the added side content.Following is a sample sidenav .html layout.

<mat-sidenav-container>
  <mat-sidenav mode="side" opened>Sidenav content</mat-sidenav>
  <mat-sidenav-content>Main content</mat-sidenav-content>
</mat-sidenav-container>

Above html snippet adds side content to a fullscreen app. To add side content to a small section of an app, we can use drawer component. This component also use 3 other components similar to above and they are - <mat-drawer-container>, <at-drawer-content>, and <mat-drawer> components.

Adding SideNav in Angular material

To add navigation, let us first generate navigation component and along with it let us also create other 2 components for our primary content.

ng g c navigation
ng g c first
ng g c second

Once, this is done let us configure our routes in app.module.ts for above created components.

app.module.ts
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { AppComponent } from './app.component';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { NavigationComponent } from './navigation/navigation.component';
import { SecondComponent } from './second/second.component';
import { FirstComponent } from './first/first.component';
import {RouterModule, Routes} from "@angular/router";
import {CustomMaterialModule} from "./core/material.module";

const appRoutes: Routes = [
  { path: '', component: FirstComponent, data: { title: 'First Component' } },
  { path: 'first', component: FirstComponent, data: { title: 'First Component' } },
  { path: 'second', component: SecondComponent, data: { title: 'Second Component' } }
];
@NgModule({
  declarations: [
    AppComponent,
    NavigationComponent,
    SecondComponent,
    FirstComponent
  ],
  imports: [
    BrowserModule,
    BrowserAnimationsModule,
    RouterModule.forRoot(
      appRoutes,
      { useHash: true }
    ),
    CustomMaterialModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

Configuring SideNav

If you hit localhost:4200 in the browser, you will see FirstComponent rendered as below but where is our NavBar!

angular6-without-navbar

Configuring sidenav is little trickier here where we have routing configured. As we know, in the SPA we have index.html that will be rendered everytime and inside this we have the selector <app-root></app-root> and in this selector AppComponent will be rendered. Simlarly, in app.component.html we have <router-outlet></router-outlet> directive defined and in this selector the different routes will be rendered. In our case, they are FirstComponent and SecondComponent. We have not configured anything as such in which our navbar would be rendered.

What we want is our navbar to be rendered and the different routes to be rendered in the main content of the navbar. To suit this requirement, we have following code in our navigation.component.html

navigation.component.html
<mat-toolbar color="warn">
  <mat-toolbar-row>
    <button type="button" aria-label="Toggle sidenav" mat-icon-button (click)="drawer.toggle()" color="primary">
      <mat-icon aria-label="Side nav toggle icon">menu</mat-icon>
    </button>
    <span><img src="./assets/devglan.png"></span>
  </mat-toolbar-row>
</mat-toolbar>
<mat-sidenav-container class="example-container">
  <mat-sidenav #drawer mode="side" opened role="navigation">
    <mat-nav-list>
      <a mat-list-item routerLink='/first'>First Component</a>
      <a mat-list-item routerLink='/second'>Second Component</a>
    </mat-nav-list>
  </mat-sidenav>
  <mat-sidenav-content>
    <router-outlet></router-outlet>
  </mat-sidenav-content>
</mat-sidenav-container>

With above code, our routes will be rendered in the main content of navbar. Following is the navigation.component.ts

navigation.component.ts
import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-navigation',
  templateUrl: './navigation.component.html',
  styleUrls: ['./navigation.component.css']
})
export class NavigationComponent implements OnInit {

  constructor() { }

  ngOnInit() {
  }

}

Take a close look of the selector i.e. app-navigation in above file. This NavBar component will be rendered in the selector app-navigation and hence with below code in our app.component.html, our NavBar can be displayed correctly.

app.component.html
<app-navigation></app-navigation>

This much of changes is enough to render our SideNav with different routes displaying in the main content.

Testing Angular Material NavBar

Now, if you hit localhost:4200, you can see folllowing view rendered. On the click of First Component we can view FirstComponent and similar for Second Component.

angular6-navbar-output

Conclusion

In this article, we discussed about implementing NavBar in Angular 6 material with sample example of an One page Application.The source can be downloaded from github here - Angular 6 Material Navbar Example. Check out my another post for https://www.devglan.com/angular/angular-hide-sidenav-login-page

Further Reading on Angular JS

1. Angular Hide Sidenav Login Page

2. Spring Boot Angular Captcha

3. Rxjs Tutorial

4. Angular Data Table Example

5. Spring Boot Jwt Auth

If You Appreciate What We Do Here On Devglan, You Should Consider:

References

Angular Sidenav