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-matcher
– https://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