Angular Routing for an Enterprise Applications

What is Angular Routing?

As we know, we can build a Single page application by using Angular. Angular will create a web application that will load a single HTML page and then dynamically update that page as the user interacts with the web application. Having support for different type of subjects in Angular like behaviour subject, async subject, etc., 

Angular has become the primary choice that helps in building accessibility in an application.

Angular supports Single page application routing module ngRoute. This routing will work based on URL, whenever a specific URL is requested by the user the routing engine will capture the URL and it will render the view based on the defined routing rules. 

In this article, we will be going to see routing conventions and patterns for a large and scalable application. By following this pattern, you will have a clean and concise organization for all your routing related concerns in your application.

Practice #1 – By creating a top-level Routes array file

Let’s understand this approach by using an example:

Step 1: Create a new file with app.routes.ts in the root src/app directory. In this app.routes.ts file, we will have our top-level Routes array.

Somethings like this:

import {Routes} from ‘@angular/router’;

export const AppRoutesRoutes = [];

Step 2: Now let’s add/register these AppRoutes in the app.module.ts file

  • Import AppRoutes from app.routes.ts in app.module.ts file.
  • Import RouterModule from @angular/router in app.module.ts file.
  • Add RouterModule.forRoot(AppRoutes ) in your import array.

After this changes your app.module.ts file will look like this:

import { NgModule } from ‘@angular/core’;

 import { BrowserModule } from ‘@angular/platform-browser’;

 import { RouterModule } from ‘@angular/router’;

 import { AppComponent } from ‘./app.component’;

 import { AppRoutes } from ‘./app.routes’;

 @NgModule({

   declarations: [AppComponent],

   imports: [BrowserModuleRouterModule.forRoot(AppRoutes)],

   providers: [],

   bootstrap: [AppComponent]

 })

 export class AppModule {}

Tip: Only add/register Top-Level routes here, in any case, if you have to implement the feature module, then the child routes would live underneath the respective feature.route.ts file. By using this pattern, we will have our top-level routes file as clean as possible.

See also  5 Benefits of GPS Tracking in a Fleet Business

Practice #2 – By creating a feature-level Routes array file

Just the same way we have created the app.routes.ts file now we will create a feature.routes.ts file to list out the individual routes for this feature module.

Step 1: First create a new file named with feature/feature.routes.ts where the feature will be the name of your module name. This file will hold our feature/module level routes array. Let’s understand it with one simple example:

import { Routes } from ‘@angular/router’;

export const FeatureModuleRoutesRoutes = [];

Step2: Now let’s add/register FeatureModueRoutes in the feature/feature.module.ts file. In the last example, we had used RouterModule.forRoot but in this example, we will have to use RouterModule.forChild.import this so these routes are automatically registered with lazyLoading:

  • Import FeatureModuleRoutes from feature.routes.ts in your ts file.
  • Import RouterModule from @angular/router in your ts file.
  • Add RouterModule.forChild(FeatureModuleRoutes) to your import array in your ts file.

Now your feature.module.ts file will look somethings like this:

 import { CommonModule } from ‘@angular/common’;

 import { NgModule } from ‘@angular/core’;

 import { RouterModule } from ‘@angular/router’;

 import { FeatureModuleRoutes } from ‘./feature.routes’;

 @NgModule({

   declarations: [],

   imports: [CommonModuleRouterModule.forChild(FeatureModuleRoutes)]

 })

 export class FeatureModule {}

And your feature.route.ts will look like this:

import { Routes } from ‘@angular/router’;

import { FeatureA1Component } from ‘./feature-A1.component’;

import { FeatureSpecificCanActivateGuard } from ‘./_guards’;

export const FeatureOneRoutesRoutes = [

  {

    path: ,

    pathMatch: ‘full’,

    redirectTo: ‘feature-one-component’

  },

  {

    path: ‘feature-one-component’,

    component: FeatureA1Component,

    canActivate: [FeatureSpecificCanActivateGuard]

  }

];

Practice #3 – By adding lazy loaded features to the top-level Routes file 

What is Lazy Loading?

Lazy loading is the concept of loading of only required components instead of loading your entire web project.

Let’s assume you have created app.routes.ts and YourModule.routes.ts, now you will have to add/register any feature module that you want to load lazily.

Step 1: Add this in your AppRoutes array in your app.route.ts file to include the new route feature:

import { Routes } from ‘@angular/router’;

export const AppRoutesRoutes = [

  {

    path: ‘feature’,

    loadChildren: () => import(‘./feature/feature.module’).then(m => m.   FeatureModule)

  }

];

See also  Placeholder or Picker in Xamarin.Forms

Now, whenever the user requests ‘/feature’ in the browser (URL section), Angular will lazy load the module using the given path and then it will automatically load any routes which are defined in the feature.routes.ts> feature array using the RouterModule.forChild import.

For any additional feature module, you will have to add another item to the AppRoutes array. If you have more than one lazy-loaded component it will look like this:

import { Routes } from ‘@angular/router’;

export const AppRoutesRoutes = [

  {

    path: ‘feature’,

    loadChildren: () => import(‘./feature/feature.module’).then(m => m. FeatureModule)

  },

   {

    path: ‘feature’,

    loadChildren: () => import(‘./feature/featureOne.module’).then(m =>  m.FeatureOneModule)

  }, {

    path: ‘feature’,

    loadChildren: () => import(‘./feature/featureTwo.module’).then(m =>  m.FeatureTwoModule)

  }

];

Practice #4 – Keep Router Guards Organized

Keeping your route guards organized is one of the important things, when you are developing large scale project. Your route guard name should suggest what functionality is going to be in there. To follow some common name structure, name your guard like:

name.function.guard.ts.

Where name will be the name of your guard like what are you guarding against?

Function which will be the function your guard will be attached to.

For example:auth.can-activate.guard.ts

Angular supports CanActivate, CanActivateChild, CanDeactivate and Resolve.

Save all your top-level guards inside the folder named with src/app/_guards. It will help you to manage your app structure, otherwise you will end up with more messy structure while trying to make it clean.

You can follow this same pattern for your feature modules, like create a new folder with ’guards’ name and store those guards.ts file in it and also make sure that you create an index.ts file to provide a clean Import structure.

So, your app structure will look something like this:

Fig: Final app structure

As you can see in this image Top-level guards are stored inside app>guards folder and feature-level guards are store inside feature>guards folder.

Conclusion

These are some of the best ways that we found which creating our project, it may possible that it can’t able to fit in your project scenarios but it is very useful and in most of the common cases you can use one of those three ways of routing in your application. 

Author Bio: Vinod Satapara Technical Director, iFour Technolab Pvt. Ltd. Technocrat and entrepreneur with years of experience building large scale enterprise web, cloud and mobile applications using latest technologies like ASP.NET, CORE, .NET MVC, Angular and Blockchain. Keen interest in addressing business problems using latest technologies and have been associated with Angular Frontend development companies.
Vinod Satapara

Logo