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/ to see
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 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
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.
Change to @typescript-eslint/parser
and paste the const routes: ....
part in the left window to see the AST tree to the right:
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 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.
Top comments (0)