Angular routing using Url Fragments

Introduction

As we all know, Angular has a very powerful routing mechanism, which allows you to specify route at the root level (using forRoot()) or child level (using forChild()) for navigating to different view/component. Route config can specify static path e.g. path: 'viewname' or dynamic (containing params) e.g. path: viewbyvalue. We won’t go into how to define configurations for routing, for basics you can refer to Guide: Routing & Navigation

Motivation

As mentioned earlier, we can use parameterized url path for navigation, which works for 99% of the cases. But the problem (yes, there always is a problem, aren’t there? 😉 ), it makes the url a tad bit longer, to read as well to parse. Though some of you will very well disagree.

The Application

So lets say we have an application which is provides a basic CRUD functionality for managing; say States of India ( I don’t know why, but lets just assume :D)

What we want to do is allow the users to

  • List all the states
  • Edit states
  • Add new states
  • Export a state

The application is very simple, and route config can be configured to match the following urls (self-explanatory :D)

What i don’t like about the above set of urls is the extra layer of route configuration that is needed; for instance

  • edit-state or edit
  • new-state or new
  • export-state or export

I want my route url to be concise and simple ( I am a simple man 🤓). I like the urls to be as follows

It is easier to read and the intent is also clear 🧐. But, Angular doesn’t allow you to define route configuration with #hash tag, so what do we do?

Solution

As always we bow our heads, put on our sniffing attire🕵️ and get to the nitty-gritty details to find a way to accomplish it. So that’s exactly what I did, and came up with a small library angular-fragment-matcher to do exactly and only this one task at hand. I have published that library over at npmjs, so that any one can use it.

Usage

Install

Get the library from npm – angular-fragment-matcherhttps://www.npmjs.com/package/angular-fragment-matcher

Fire up your favorite command prompt and type

npm i angular-fragment-matcher

Configuring route config

Define the route for which you intend to use the url fragment for routing

Configuring metadata

The RouteMatchService.urlFragmentMatcher requires metadata config data, inorder to match a route successfully. The following config information need to be provided in data object for the route config ( we are going to reuse as much as possible :))

 matcherconfig : {
  fragment: 'new' // the name of the fragment which will be checked 
                  // i.e. <appurl>\states\#new
}

Complete route config, will look as follows:

const routes: Routes = [{
    path: "",
    children : [{
      component: StateComponent,
      matcher: RouteMatchService.urlFragmentMatcher,
      data : {
        matcherconfig : {
          fragment: 'new'
        }
      }
    }]
}]

Inject RouteMatchService

Inorder to configure route config to use custom url matcher, we need to inject the RouterMatcherService in the feature module.

import { RouteMatchService } from 'angular-fragment-matcher';

Add the `RouteMatchModule` to the `imports` collection

@NgModule({
  imports: [ ..., RouterModule.forChild(routes), RouteMatchModule ],
  declarations: [ ... ],
  providers: [ {
    provide: RouteMatchService,
    useFactory : routeMatchServiceFactory, 
    deps : [ Router ]
    } ],
  exports: [ RouterModule ]
})
export class StatesModule {
  constructor(private routeMatchService: RouteMatchService) {}
}

Demo

Time for a small demo, for that you need to head over to StackBlitz

View on StackBlitz ⚡️

Leave a comment