Originally published by Didin J at https://www.djamware.com
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.
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.
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
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/documentation/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.
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.
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.
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.
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.
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.
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
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>
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.
Thanks for reading ❤
If you liked this post, share it with all of your programming buddies!
Follow us on Facebook | Twitter
☞ Angular 8 (formerly Angular 2) - The Complete Guide
☞ Angular & NodeJS - The MEAN Stack Guide
☞ The Complete Node.js Developer Course (3rd Edition)
☞ Best 50 Angular Interview Questions for Frontend Developers in 2019
☞ How to build a CRUD Web App with Angular 8.0
☞ React vs Angular: An In-depth Comparison
☞ React vs Angular vs Vue.js by Example
☞ Microfrontends — Connecting JavaScript frameworks together (React, Angular, Vue etc)
☞ Building CRUD Mobile App using Ionic 4, Angular 8
☞ How to Build Mobile Apps with Angular, Ionic 4, and Spring Boot
☞ Ionic 4 & Angular Tutorial For Beginners - Crash Course
#angular #web-development #node-js #javascript