3
votes

dashboard.html

<ul class="nav flex-column">
  <li class="nav-item">
    <a class="nav-link" routerLink='/dashboard'>Dashboard</a>
  </li>
  <li class="nav-item" *ngFor="let cat of categories; let i = index">
    <a class="nav-link" [routerLink]="cat.categories">
      <i class="fa fa-{{cat.Icon}}" aria-hidden="true"></i>
      &nbsp;{{cat.categories}}
    </a>
  </li>
</ul>

I am generating a list dynamic, it is just like

<li>Page1</li>
<li>Page2</li>
<li>Page3</li>
<li>Page4</li>

and my current route is "http://localhost:4200/dashboard". Now i want to route when i click on

<a class="nav-link" [routerLink]="cat.categories">
  <i class="fa fa-{{cat.Icon}}" aria-hidden="true"></i>&nbsp; 
  {{cat.categories}}
</a>

the desired route is "http://localhost:4200/dashboard/page1". It works fine when I click the first time, but when I click on another link it gives me the error

core.js:1673 ERROR Error: Uncaught (in promise): Error: Cannot match any routes. URL Segment: 'dashboard/page1/page2'.

app-routing.module.ts

{ path: 'dashboard', component: DashboardComponent, canActivate: [AuthGuard] },
{ path: 'dashboard/:name', component: DashboardComponent, canActivate: [AuthGuard] }
2

2 Answers

2
votes

Change your routerLink by prepending /dashboard/:

[routerLink]="'/dashboard/' + cat.categories"

If the first segment begins with /, the router will look up the route from the root of the app.

If the first segment begins with ./, or doesn't begin with a slash, the router will instead look in the children of the current activated route.

And if the first segment begins with ../, the router will go up one level.

0
votes

My solution for this issue is using a service like SetRouterService.ts as below

import { Injectable } from '@angular/core';

import { Router } from '@angular/router';

@Injectable()

export class SetRouterService {

constructor(  private router: Router ) {}

public set_router( routing , route  ) {

  if ( routing.data == false ) { // router without any data in url ..... ...........................

    if( routing.relative == true ){

      this.router.navigate( [ routing.path ],

          {
            relativeTo: route
          }
      );

    }else{

      this.router.navigate( [ routing.path ] );
    }
    return;
  }

  // router with data in url ..........................................

  let paramsInUrl:any = {};

  if( routing.data instanceof Array ){   //  array of object with params ..........................................

      for( let param of routing.data ){ // loop

          paramsInUrl[param.keyparams] = param.params.toString();
      }

  }else{ // single param ....................................

      paramsInUrl = { [routing.data.keyparams] : routing.data.params.toString() };
  }


  if( routing.relative == true){

    this.router.navigate( [ routing.path ] ,

        {
            relativeTo: route ,  queryParams: paramsInUrl
        }
    );

  }else{

    this.router.navigate( [ routing.path ] ,

        {
            queryParams: paramsInUrl
        }
    );
  }
return;
}

}

so you can import it where you want to use it as below

import { SetRouterService } from '../../../share_services/set-router.service';

import { ActivatedRoute } from '@angular/router';

export class componentName implements OnInit  {

   constructor(

       private setRouter :SetRouterService ,

       private route:ActivatedRoute ,

   ){}
}

then you can use it just call set_router method and pass parameters with object that you need for specific navigation
parameters that you can pass are : path , data is to set params with array or false when you don't need to set params in route , relative true or false as example below

let router = { path:'shopping/products/'+dynamic_path , data:
    [
      {keyparams :'id', params:  category.id },
      {keyparams :'page', params:  1 }

    ] , relative:false };

this.setRouter.set_router( router , this.route );