eslint rule to check for bogus routes
Tags: angular, eslint, routing
Published: 2022-07-29 17:20:35

I recently had a problem with a route in angular that contained a white-space character in the path value. Fortunately eslint came to rescue.

## The setup

Just create a new angular project and add two components

```
ng new routerrule --routing
cd routerrule/
ng g c foo --skip-tests && ng g c bar --skip-tests
```
Fire up your favorite editor, change _src/app/app.component.html_ to contain the following:

```

<h2>Router test</h2>
<ul>
  <li><a routerLink="foo">foo</a></li>
  <li><a routerLink="bar">bar</a></li>
</ul>
<router-outlet></router-outlet>
```

Also change _src/app/app-routing.module.ts_ to:

```
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { BarComponent } from './bar/bar.component';
import { FooComponent } from './foo/foo.component';

const routes: Routes = [
  { path: 'foo', component: FooComponent },
  { path: 'bar', component: BarComponent }
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule { }

```
Then start a test server with `ng serve` and navigate to [http://localhost:4200/](http://localhost:4200/) to see
![a simple angular app](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/59704eqmo71caadb3waq.png)

Clicking on either of the two links will display some nice messages. 

## The problem

The problem will occur when you change one of the paths values in _src/app/app-routing.module.ts_ to start with a space. So change for example the path value for 'bar' to ' bar':

```
  { path: ' bar', component: BarComponent }
```
When you now click on the according link nothing will happen and you will see an `Error: NG04002: Cannot match any routes. URL Segment: 'bar'` in the console.

The problem here is that these white-spaces are hard to spot in the code!

## The solution

Leverage [eslint](https://eslint.org/) to find those white-space characters at the beginning and the end of string values. First do a 

```
ng lint
```
to add the linter to your project. This will also add the _.eslintrc.json_ file. 

Now comes the fun part: What rule should be used? That's relative simple, we can use the [`no-restricted-syntax`](https://eslint.org/docs/latest/rules/no-restricted-syntax) rule, also the description doesn't really fit our problem description.
But what is the selector value for this rule? You can find this out by using the [AST Explorer](https://astexplorer.net).
Change to `@typescript-eslint/parser` and paste the `const routes: ....` part in the left window to see the [AST tree](https://astexplorer.net/#/gist/e312115a5531b615da3a4ceef93cb032/34a94b51197d18262bca35a9cbea6326badca6c0) to the right:

![AST explorer result](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/62ifa6bt89w1co9y5ols.png)

When you click on ' bar' the needed information for the selector will be revealed: `Property` and `value.value`

With this info and the [attribute regex selector](https://eslint.org/docs/latest/developer-guide/selectors#what-syntax-can-selectors-have) we can add our additional rule to the rules section of _.eslintrc.json_ :

```
...
      "rules": {
        "@angular-eslint/directive-selector": [
          "error",
          {
            "type": "attribute",
            "prefix": "app",
            "style": "camelCase"
          }
        ],
        "@angular-eslint/component-selector": [
          "error",
          {
            "type": "element",
            "prefix": "app",
            "style": "kebab-case"
          }
        ],
        "no-restricted-syntax": [
          "warn",
          {
            "selector": "Property[value.value=/^\\s+|\\s+$/]",
            "message": "Please trim your values"
          }
        ]
      }
...
```
The first two rules are default rules, we just added the third one.

If you now do a `ng lint` again you will get a nice warning. Also some editors will directly show that there is something wrong with your code.


![ng lint output](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/x4ht80bi29u6m15b01bc.png)