Alwin Richard
Alwin Richard

Reputation: 138

Same path and same number of parameters but different components for routing in Angular 5 application

app.routing.module.ts

const routes: Routes = [
    { path: '', component: AComponent },
    ...
    { path: 'homes/:id/:rate/:item', component: HomesComponent},
    { path: 'details/:id/:name/:product', component: DetailComponent},
    ...
]

As per client's requirement, we need to change the path to homes for both components. So we've updated the app.routing.module.ts.

Updated app.routing.module.ts

const routes: Routes = [
    { path: '', component: AComponent },
    ...
    { path: 'homes/:id/:rate/:item', component: HomesComponent},
    { path: 'homes/:id/:name/:product', component: DetailComponent},
    ...
]

but, due to the same number of parameters that we're using in each component we are getting conflict and it's not rendering properly, for all condition it is routing to HomesComponent that we've given first in the Routes list.

Do you guys have any suggestions to resolve this issue, without compromising the path and number of parameters?

Upvotes: 2

Views: 5146

Answers (3)

Prashanth S
Prashanth S

Reputation: 91

When for scenario like above, depends upon query parameter and not as route param, i find @ritaj's answer useful with few more lines of code to check for the routes like below. As UrlMatcher does not seem to have access to activated route and thus the params with it.

Route

{ path: 'apply', component: ApplicationRouterComponent },

Route handler component

export class ApplicationRouterComponent implements OnInit {

  type: string;
  state: string;

  constructor(private route: ActivatedRoute) { }

  ngOnInit() {
    this.route.queryParams.subscribe(q => {
      this.type = q['type'];
      this.state = q['state'];
    });
  }

  showApplicationForm(): boolean {
    return this.type !== 'new' || this.state !== 'inprogress';
  }

  showInProgressForm(): boolean {
    return this.type === 'new' && this.state === 'inprogress';
  }

}

Route handler html

<app-application *ngIf="showApplicationForm()"></app-application>
<app-resume *ngIf="showInProgressForm()"></app-resume>

Upvotes: 1

Karthick Manoharan
Karthick Manoharan

Reputation: 681

Use custom UrlMatcher when paths and parameters are not helpful

Form official doc: A custom URL matcher can be provided when a combination of path and pathMatch isn't expressive enough

In your case i would create a custom matcher.

SOLUTION 1:

export const routes = [{ 
  matcher: homeCustomerMatcher,
  component: HomeComponent 
}, {
  matcher: detailsCustomerMatcher,
  component: DetailsComponent
}];

Scenario A: If the data types are different for parameters. Assuming/:rate params is number data type and /:name is string

export function homeCustomerMatcher(url: UrlSegment[]){
 return url.length === 3 && isInteger(url[1].path * 1) ? ({consumed: url}) : null;
}

Scenario B: If the /:name values are pre defined. Assuming:/rate and :/name is same date type

In this case we can create a collection/array of possible name values and compare the values again the path values.

const possibleNameValues = ["A","B","C"];
export function homeCustomerMatcher(url: UrlSegment[]){
 return url.length === 3 &&  possibleNameValues.includes(url[1].path)  
 ? ({consumed: url}) : null;
}

SOLUTION 2:

Using regexwith UrlMatcher to match the param data type

  {
    path: 'homes/:id',
    children: [
        {
            path: ':rate',
            matcher: NumericUrlMatcher,
            component: Ratecomponent
        },
        {
            path: ':name',
            component: NameComponent
        }
   }

Now you customer matcher function should be updated to

 export function NumericUrlMatcher(url: UrlSegment[]) {
    const regex = new RegExp(...);
    const match = url[0].path.match(regex);
    return match !== null && match[0].length === url[0].path.length;
  }

Upvotes: 10

Roberto Zvjerković
Roberto Zvjerković

Reputation: 10127

You could make a wrapper component with the path and programatically route to different components.

const routes: Routes = [
    { path: '', component: AComponent },
    ...
    { path: 'homes/:id/:rate/:item', component: WrapperComponent},
    ...
]

Wrapper template:

<detail-component *ngIf="yourCondition"><detail-component>
<home-component *ngIf="!yourCondition"></home-component>

How would you go about finding the first method for yourCondition I don't know.

However, I would definitely advise against this.

Upvotes: 4

Related Questions