<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: OcasoProtal</title>
    <description>The latest articles on DEV Community by OcasoProtal (@ocasoprotal).</description>
    <link>https://dev.to/ocasoprotal</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F223598%2F27211082-58cf-41fa-8e12-a9d638f1c8e8.jpeg</url>
      <title>DEV Community: OcasoProtal</title>
      <link>https://dev.to/ocasoprotal</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ocasoprotal"/>
    <language>en</language>
    <item>
      <title>eslint rule to check for bogus routes</title>
      <dc:creator>OcasoProtal</dc:creator>
      <pubDate>Fri, 29 Jul 2022 17:20:35 +0000</pubDate>
      <link>https://dev.to/ocasoprotal/eslint-rule-to-check-for-bogus-routes-1ib3</link>
      <guid>https://dev.to/ocasoprotal/eslint-rule-to-check-for-bogus-routes-1ib3</guid>
      <description>&lt;p&gt;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.&lt;/p&gt;

&lt;h2&gt;
  
  
  The setup
&lt;/h2&gt;

&lt;p&gt;Just create a new angular project and add two components&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ng new routerrule --routing
cd routerrule/
ng g c foo --skip-tests &amp;amp;&amp;amp; ng g c bar --skip-tests
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Fire up your favorite editor, change &lt;em&gt;src/app/app.component.html&lt;/em&gt; to contain the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
&amp;lt;h2&amp;gt;Router test&amp;lt;/h2&amp;gt;
&amp;lt;ul&amp;gt;
  &amp;lt;li&amp;gt;&amp;lt;a routerLink="foo"&amp;gt;foo&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;
  &amp;lt;li&amp;gt;&amp;lt;a routerLink="bar"&amp;gt;bar&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;
&amp;lt;/ul&amp;gt;
&amp;lt;router-outlet&amp;gt;&amp;lt;/router-outlet&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Also change &lt;em&gt;src/app/app-routing.module.ts&lt;/em&gt; to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;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 { }

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then start a test server with &lt;code&gt;ng serve&lt;/code&gt; and navigate to &lt;a href="http://localhost:4200/"&gt;http://localhost:4200/&lt;/a&gt; to see&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--e_j_zBzA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/59704eqmo71caadb3waq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--e_j_zBzA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/59704eqmo71caadb3waq.png" alt="a simple angular app" width="271" height="200"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Clicking on either of the two links will display some nice messages. &lt;/p&gt;
&lt;h2&gt;
  
  
  The problem
&lt;/h2&gt;

&lt;p&gt;The problem will occur when you change one of the paths values in &lt;em&gt;src/app/app-routing.module.ts&lt;/em&gt; to start with a space. So change for example the path value for 'bar' to ' bar':&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  { path: ' bar', component: BarComponent }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When you now click on the according link nothing will happen and you will see an &lt;code&gt;Error: NG04002: Cannot match any routes. URL Segment: 'bar'&lt;/code&gt; in the console.&lt;/p&gt;

&lt;p&gt;The problem here is that these white-spaces are hard to spot in the code!&lt;/p&gt;

&lt;h2&gt;
  
  
  The solution
&lt;/h2&gt;

&lt;p&gt;Leverage &lt;a href="https://eslint.org/"&gt;eslint&lt;/a&gt; to find those white-space characters at the beginning and the end of string values. First do a&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ng lint
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;to add the linter to your project. This will also add the &lt;em&gt;.eslintrc.json&lt;/em&gt; file. &lt;/p&gt;

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

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--i470VLYk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/62ifa6bt89w1co9y5ols.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--i470VLYk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/62ifa6bt89w1co9y5ols.png" alt="AST explorer result" width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When you click on ' bar' the needed information for the selector will be revealed: &lt;code&gt;Property&lt;/code&gt; and &lt;code&gt;value.value&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;With this info and the &lt;a href="https://eslint.org/docs/latest/developer-guide/selectors#what-syntax-can-selectors-have"&gt;attribute regex selector&lt;/a&gt; we can add our additional rule to the rules section of &lt;em&gt;.eslintrc.json&lt;/em&gt; :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;...
      "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"
          }
        ]
      }
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The first two rules are default rules, we just added the third one.&lt;/p&gt;

&lt;p&gt;If you now do a &lt;code&gt;ng lint&lt;/code&gt; again you will get a nice warning. Also some editors will directly show that there is something wrong with your code.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--v3Sgu1zw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/x4ht80bi29u6m15b01bc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--v3Sgu1zw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/x4ht80bi29u6m15b01bc.png" alt="ng lint output" width="768" height="233"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>angular</category>
      <category>eslint</category>
      <category>routing</category>
    </item>
  </channel>
</rss>
