Angular 8 Tutorial: Routing & Navigation Example

by Didin J. on Aug 18, 2019 Angular 8 Tutorial: Routing & Navigation Example

A comprehensive example of Angular 8 Routing & Navigation to help make easier to understanding the Angular Routing concepts

The Angular 8 Router uses to navigate between views or pages that trigger by the user actions. Its a standard behavior in the web application, PWA, or Mobile Apps. The navigation or view changes happen when the user clicks on the link, click on the button, or enter the URL from the browser address bar. Every view change can bring the params of data from the previous view to the next view.


Table of Contents:


In this tutorial, we will implement the Angular Routing & Navigation starting with the simple web application navigation of just a few pages or views. Then continue with more views and nested views completed with send/get params, animated transitions, child routing, etc.


Preparation

The following tools, frameworks, libraries, and modules are required for this tutorial:

So, make sure all of those items are installed in your machine and ready to run. We assume you are successfully installing Node.js and has runnable NPM command then we have to check the right version for the Node.js and the NPM command by open your terminal or Node.js command line then type these commands.

node -v
v10.15.1
npm -v
6.10.2

That Node.js and NPM versions that we use are the stable and recommended version. Next, we have to install Angular CLI by type this command.

sudo npm install -g @angular/cli

Now, we have the latest version of Angular when this example was written.

ng version

Angular Routing Navigation - Home Page

Next, create an Angular 8 application for this Routing & Navigation example by typing this command.

ng new angular-routing

Answer all questions like below which we will use Angular Routing and SCSS as a stylesheet.

? Would you like to add Angular routing? Yes
? Which stylesheet format would you like to use? SCSS   [ https://sass-lang.com/documentat
ion/syntax#scss                ]

Next, to sanitize the newly created Angular 8 project go to that project folder then run the Angular application.

cd ./angular-routing
ng serve

You will this page or view when you open "http://localhost:4200/" in your browser which means the Angular 8 is ready to go.

Angular Routing Navigation - Welcome

If you open the project using your IDE or text editor, there is a starting component app.component.html as the default Root view. This component is the default view that trigger from the index.html using <app-root></app-root> tag and the root of the application URL determine by <base href="/"> in index.html. There also an empty array of routing when you see in `src/app/app-routing.module.ts`.

const routes: Routes = [];

Next, we will put all views routing and navigation inside that Routes array.


Simple Angular Routing

The simple Angular 8 Routing will contain a few pages or views that have the same level each other. We describe this simple Angular Routing & Navigation by this diagram.

Angular Routing Navigation - Diagram

From that diagram, we need to create the new components by type this command to generate it using Angular Schematics.

ng g component Home
ng g component About
ng g component Privacy
ng g component Terms

Now, we have a home, about, privacy, and terms folders inside the app folder. Next, we have to add routing for those components by open and edit `src/app/app-routing.module.ts` then add those components imports.

import { HomeComponent } from './home/home.component';
import { AboutComponent } from './about/about.component';
import { PrivacyComponent } from './privacy/privacy.component';
import { TermsComponent } from './terms/terms.component';

Next, add or modify the constant variable of routes by this array of component routes.

const routes: Routes = [
  { path: 'home', component: HomeComponent },
  { path: 'about', component: AboutComponent },
  { path: 'privacy', component: PrivacyComponent },
  { path: 'terms', component: TermsComponent },
  { path: '', redirectTo: '/home', pathMatch: 'full' }
];

That's mean those components are accessible through these URLs.

  • http://localhost:4200/home -> navigate to HomeComponent
  • http://localhost:4200/about -> navigate to AboutComponent
  • http://localhost:4200/privacy -> navigate to PrivacyComponent
  • http://localhost:4200/terms -> navigate to TermsComponent
  • http://localhost:4200/ -> redirect to HomeComponent

All of those Components routes wrapped inside app.component.html by the line <router-outlet></router-outlet>. Dynamic views changes inside the router-outlet tag. So, we can use the rest of app.component.html view for the navigation header. We will use Angular Bootstrap module to make the nice UI/UX. Next, install the ng-bootstrap module using this command.

npm install --save @ng-bootstrap/ng-bootstrap

Next, import to `src/app/app.module.ts`.

import { NgbModule } from '@ng-bootstrap/ng-bootstrap';

Also, add it to @NgModule imports array.

imports: [
  BrowserModule,
  AppRoutingModule,
  NgbModule
],

Add this stylesheet reference to the Bootstrap stylesheet in the index.html before the closing of head tag.

<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" />

Next, we have to modify the `src/app/app.component.html` file to replace all HTML tags except <router-outlet></router-outlet> tag.

<nav class="navbar navbar-expand-lg navbar-light bg-light">
  <a class="navbar-brand" routerLink="">Angular Routing</a>
  <button class="navbar-toggler" type="button" (click)="toggleNavbar()" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
    <span class="navbar-toggler-icon"></span>
  </button>

  <div class="collapse navbar-collapse" [ngClass]="{ 'show': navbarOpen }">
    <ul class="navbar-nav mr-auto">
      <li class="nav-item active">
        <a class="nav-link" routerLink="" routerLinkActive="active">Home <span class="sr-only">(current)</span></a>
      </li>
      <li class="nav-item">
        <a class="nav-link" routerLink="about" routerLinkActive="active">About Us</a>
      </li>
      <li class="nav-item">
        <a class="nav-link" routerLink="privacy" routerLinkActive="active">Privacy Policy</a>
      </li>
      <li class="nav-item">
        <a class="nav-link" routerLink="terms" routerLinkActive="active">Terms and Conditions</a>
      </li>
    </ul>
  </div>
</nav>

<div class="container">
  <router-outlet></router-outlet>
</div>

We add the toggleNavbar() function to make this Boostrap responsive and the menu working on the thinner width. Open and edit `src/app/app.component.ts` then add these variable and function.

navbarOpen = false;

toggleNavbar() {
  this.navbarOpen = !this.navbarOpen;
}

The navigation works by click on the navigation item and it's done by the Angular [routerLink]. To marked active view in the Boostrap navigation bar, the Angular routerLinkActivate just use inline with the [routerLink]. And here's how it works.

Angular Routing Navigation - Preview


Angular Wildcard Route

From the previous example of the simple Angular Routing you just can navigate to the routing that defines in the app-routing.module.ts. Unfortunately, when you point to different URL other than that, the view will be redirected to the root URL. If you want to handle invalid URL navigation error, you can redirect the entire undefined router by the wildcard route that defines with two asterisks "**".

Next, open and edit again `src/app/app-routing.module.ts` then add this wildcard route below other routes. So, it will look like this.

const routes: Routes = [
  { path: 'home', component: HomeComponent },
  { path: 'about',        component: AboutComponent },
  { path: 'privacy',        component: PrivacyComponent },
  { path: 'terms',        component: TermsComponent },
  { path: '',   redirectTo: '/home', pathMatch: 'full' },
  { path: '**', component: PageNotFoundComponent }
];

That wildcard route required a PageNotFoundComponent. For that, generate a new component by this command.

ng g component PageNotFound

Import that component in `src/app/app-routing.module.ts` file.

import { PageNotFoundComponent } from './page-not-found/page-not-found.component';

Make a little modification to the `src/app/page-not-found/page-not-found.component.html` file by these lines of HTML tags.

<div class="row">
  <div class="col-md-12">
      <div class="error-template">
          <h1>
              Oops!</h1>
          <h2>
              404 Not Found</h2>
          <div class="error-details">
              Sorry, an error has occured, Requested page not found!
          </div>
          <div class="error-actions">
              <a routerLink="" class="btn btn-primary btn-lg"><span class="glyphicon glyphicon-home"></span>
                  Take Me Home </a>
          </div>
      </div>
  </div>
</div>

Now, when you point to the URL http://localhost:4200/otherpage, you will see this view with a button that takes to the home view.

Angular Routing Navigation - Page Not Found


Angular Routing & Navigation for Modular Web Application

For the modular web application, Angular Routing & Navigation configuration can use separate routing file for each module. Let's try by add two new models using these commands.

ng generate module articles/articles --module app --flat --routing
ng generate module products/products --module app --flat --routing

That commands will generate articles and products modules with their own module and routing module files. It also registers that modules to the `src/app/app.module.ts`. But, we have to set order of AppRoutingModule to be the last after above-added modules. For that, open and edit `src/app/app.module.ts` then modify the @NgModule imports array order.

imports: [
  BrowserModule,
  NgbModule,
  ArticlesModule,
  ProductsModule,
  AppRoutingModule
],

If change the order of the imports for AppRoutingModule to be the last, then we can navigate to http://localhost:4200/artilces because the Angular app catches the wildcard route first. Next, we will add the list and details views to each module.

ng g component articles/articles
ng g component articles/article-details
ng g component products/products
ng g component products/product-details

That commands will automatically be added or registered that components to each module file. So, the structure of the whole Angular application will be like this.

|-- app
|   |-- about
|   |   |-- about.component.html
|   |   |-- about.component.scss
|   |   |-- about.component.spec.ts
|   |   `-- about.component.ts
|   |-- app-routing.module.ts
|   |-- app.component.html
|   |-- app.component.scss
|   |-- app.component.spec.ts
|   |-- app.component.ts
|   |-- app.module.ts
|   |-- articles
|   |   |-- article-details
|   |   |   |-- article-details.component.html
|   |   |   |-- article-details.component.scss
|   |   |   |-- article-details.component.spec.ts
|   |   |   `-- article-details.component.ts
|   |   |-- articles
|   |   |   |-- articles.component.html
|   |   |   |-- articles.component.scss
|   |   |   |-- articles.component.spec.ts
|   |   |   `-- articles.component.ts
|   |   |-- articles-routing.module.ts
|   |   `-- articles.module.ts
|   |-- home
|   |   |-- home.component.html
|   |   |-- home.component.scss
|   |   |-- home.component.spec.ts
|   |   `-- home.component.ts
|   |-- page-not-found
|   |   |-- page-not-found.component.html
|   |   |-- page-not-found.component.scss
|   |   |-- page-not-found.component.spec.ts
|   |   `-- page-not-found.component.ts
|   |-- privacy
|   |   |-- privacy.component.html
|   |   |-- privacy.component.scss
|   |   |-- privacy.component.spec.ts
|   |   `-- privacy.component.ts
|   |-- products
|   |   |-- product-details
|   |   |   |-- product-details.component.html
|   |   |   |-- product-details.component.scss
|   |   |   |-- product-details.component.spec.ts
|   |   |   `-- product-details.component.ts
|   |   |-- products
|   |   |   |-- products.component.html
|   |   |   |-- products.component.scss
|   |   |   |-- products.component.spec.ts
|   |   |   `-- products.component.ts
|   |   |-- products-routing.module.ts
|   |   `-- products.module.ts
|   `-- terms
|       |-- terms.component.html
|       |-- terms.component.scss
|       |-- terms.component.spec.ts
|       `-- terms.component.ts
|-- assets
|-- environments
|   |-- environment.prod.ts
|   `-- environment.ts
|-- favicon.ico
|-- index.html
|-- main.ts
|-- polyfills.ts
|-- styles.scss
`-- test.ts


Angular Route Parameters

Now, we will add a route for each component in each module. The details component route will contain a parameter. For the articles route, open and edit `src/app/articles/articles-routing.modules.ts` then add these imports.

import { ArticlesComponent } from './articles/articles.component';
import { ArticleDetailsComponent } from './article-details/article-details.component';

Add the routes for those components.

const routes: Routes = [
  { path: 'articles', component: ArticlesComponent },
  { path: 'article/:id', component: ArticleDetailsComponent }
];

You can see the parameter in the [article/: id] route path. To send parameters to that route, we can use the [routerLink] to send data to that params. To do that, open and edit `src/app/articles/articles/articles.component.html` then add this [routerLink] to the anchor.

<a [routerLink]="['/article', article.id]" class="btn btn-success btn-lg">Show Details</a>

Next, add that article object to `src/app/articles/articles/articles.component.ts` before the constructor.

article = {
  id: 100,
  title: 'How to make router & navigation in Angular 8',
  author: 'Didin J.',
  description: 'A complete tutorial about creating router and navigation in the Angular 8 Web Application'
};

To read the params that sent from the articles view, open and edit `src/app/articles/article-details/article-details.component.ts` then add this import of ActivatedRoute.

import { ActivatedRoute } from '@angular/router';

Inject that module to the constructor.

constructor(private activatedRoute: ActivatedRoute) {}

Read the ID from the route params using ActivatedRoute inside the constructor bracket.

this.id = this.activatedRoute.snapshot.params.id;

or

this.id = this.activatedRoute.snapshot.paramMap.get('id');

The params set as id variable, so, add an id variable before the constructor.

id: any;

Next, we can display the route params that get using ActivatedRoute to the details view. Open and edit `src/app/articles/articles/article-details.component.html` then change the HTML tags to these lines of HTML tags.

<h1>The Details of Article with an ID: {{id}}</h1>

An alternative way, we can navigate from articles to article details view with params programmatically using Typescript code. Add import of Angular Routes to `src/app/articles/articles/articles.component.ts`.

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

Inject the Routes to the constructor.

constructor(private router: Router) { }

Add a function to navigate to the article details.

gotoDetails(articleId: any) {
  this.router.navigate(['/article/', articleId]);
}

Next, change the [routerLink] to (click) attribute in the `src/app/articles/articles/articles.component.html`.

<a (click)="gotoDetails(article.id)" class="btn btn-secondary btn-lg">Show Details</a>

Next, you can create do the same way to the products module then add the navigation menu of products to `src/app/app.component.html`.

<li class="nav-item">
  <a class="nav-link" routerLink="products" routerLinkActive="active">Products</a>
</li>


Add Angular Animation to The Routed Component

The example that shows above has no transition. For that, we have to add Angular animation to make animated navigation transition. Transition with animation can be applied to each component. Next, open and edit `src/app/app.module.ts` then add this import of BrowserAnimationModule.

import { BrowserAnimationsModule } from '@angular/platform-browser/animations';

Add to @NgModule imports after BrowserModule.

imports: [
  BrowserModule,
  BrowserAnimationsModule,
  ...
],

We will add the transition to only Articles module. For that, open and edit `src/app/articles/articles-routing.module.ts` then modify the route variable to add animation as a data field.

const routes: Routes = [
  { path: 'articles', component: ArticlesComponent, data: { animation: 'articles' } },
  { path: 'article/:id', component: ArticleDetailsComponent, data: { animation: 'article' } }
];

Next, create the `src/app/animation.ts` file to configure the animation style then fill that file with these Typescript codes.

import {
  trigger, animateChild, group,
  transition, animate, style, query
} from '@angular/animations';


// Routable animations
export const slideInAnimation =
  trigger('routeAnimation', [
    transition('articles <=> article', [
      style({ position: 'relative' }),
      query(':enter, :leave', [
        style({
          position: 'absolute',
          top: 0,
          left: 0,
          width: '100%'
        })
      ]),
      query(':enter', [
        style({ left: '-100%'})
      ]),
      query(':leave', animateChild()),
      group([
        query(':leave', [
          animate('300ms ease-out', style({ left: '100%'}))
        ]),
        query(':enter', [
          animate('300ms ease-out', style({ left: '0%'}))
        ])
      ]),
      query(':enter', animateChild()),
    ])
  ]);

Add that animation configuration to `src/app/app.component.ts` by import it first along with RouterOutlet module.

import { slideInAnimation } from './animations';
import { RouterOutlet } from '@angular/router';

Add that animation to the @Component object.

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss'],
  animations: [ slideInAnimation ]
})

Add a function to enable animation on the routeable animation views.

getAnimationData(outlet: RouterOutlet) {
  return outlet && outlet.activatedRouteData && outlet.activatedRouteData.animation;
}

Next, add route animation to the div that wrapped <router-outlet>.

<div class="container" [@routeAnimation]="getAnimationData(routerOutlet)">
  <router-outlet #routerOutlet="outlet"></router-outlet>
</div>

Now, you will see the animated transition when going to Article Details from articles and vice versa.

That it's, the basic Angular Routing & Navigation. For more deeps about Angular Routing, we will write another example about it later. For this example, you can get the full source code in our GitHub.

If you don’t want to waste your time design your own front-end or your budget to spend by hiring a web designer then Angular Templates is the best place to go. So, speed up your front-end web development with premium Angular templates. Choose your template for your front-end project here.

That just the basic. If you need more deep learning about MEAN Stack, Angular, and Node.js, you can take the following cheap course:

Thanks!

Loading…