Leguest
Leguest

Reputation: 2137

Dynamic page URLs in Angular

I have following router config:

@NgModule({
 imports: [
  RouterModule.forChild([
   { path: 'office', component: OfficePage},
   { path: 'office/:category1/', component: OfficeInnerPage},
   { path: 'office/:category1/:category2', component: OfficeInnerPage},
   { path: 'office/:category1/:category2/:category3', component: OfficeInnerPage},
   { path: 'office/:category1/:id', component: DetailPage}
  ])
 ],
})

OfficeInerPage - List of items Controller

DetailPage - Detail item Controller

:id example os10198

URL examples

http://example.com/office/business_center/subway/

http://example.com/office/business_center/subway/arbat

http://example.com/office/business_center/os10198

Problem

Angular router state :category1/:category2/ rewrites :category1/:id state. How can I fix this?

Upvotes: 0

Views: 459

Answers (2)

Leguest
Leguest

Reputation: 2137

I have found a solution.

Somewhere in router (source code). I found property matcher, it is a Function which allows you handle route by yourself.

In my case I write following function:

function pathMatcher(segments: UrlSegment[], group: UrlSegmentGroup, route: Route) {

  if (segments.length > 2) {

    if(segments[2].path.match(/([\w|]+[\d]+)/)) {

      let posParams = {'id': segments[2]};

      return {consumed: segments, posParams: posParams};

    } else {
    return null;
    }
  } else {
   return null;
  }

}

And my router config:

@NgModule({
  imports: [
    RouterModule.forChild([
      {path: 'office', component: OfficePage},
      {path: 'office/:category1', component: OfficeInnerPage},
      {path: 'office/:category1/:category2/:category3', component: OfficeInnerPage},
      {path: 'office/:category1/:category2/:category3/:category4', component: OfficeInnerPage},
      {matcher: <any>pathMatcher, component: DetailPage}, // <- here is matcher, also its conflicts with path property
      {path: 'office/:category1/:category2', component: OfficeInnerPage}, // it should be below state with matcher
    ])
 ],
})

Now I resolve correct these types of links:

http://example.com/office/business_center/subway/ http://example.com/office/business_center/os10198

P.S. Useful gist

Upvotes: 1

Poul Kruijt
Poul Kruijt

Reputation: 71891

You need to add an extra path name, for instance:

{path: 'office/:category1/item/:id', component: DetailPage}

Otherwise angular has no way of knowing whether you want to go to :category2 or :id, and because you have :id as the last thing in your array, it will overrule the first one

Upvotes: 1

Related Questions