Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular2 - How to use router with dynamic urls

Tags:

angular

Suppose I have this nested itemListComponent, which is a child of a rootComponent, using the following template:

<span *ngFor="#item of list">
    <a [routerLink]="[item.url]">{{item.title}}</a> |
</span>

The path item.url, which is provided from a Json service, could have one of the following path structure:

  • /category1/(a content id)/(a title connected with dashes(-))
  • /category2/(a content id)/(a title connected with dashes(-))
  • /category3/(a content id)/(a title connected with dashes(-))

Examples:

category2/987654/hello-world
category2/123456/hi-teacher
category3/554433/yo-brother

How could @RouteConfig be implemented so that these links use a itemDetail component?

Sorry if this does not look very detailed. I did not find a clear how-to-guide for routing urls that are provided by a service with full paths (not assembled paths)

like image 630
Pat M Avatar asked Mar 24 '16 18:03

Pat M


2 Answers

Try this:

<span *ngFor="#item of list">
   <a [routerLink]="['/category', item.url]">
        {{item.title}}
   </a>
</span>

routes.ts:

{path: "category/:id", component: CategoryComponent}
like image 156
Ivan Pianetti Avatar answered Sep 23 '22 12:09

Ivan Pianetti


That's what regex matches are for. But if you have pre-assembled URLs you may not want to use routerLink with them. RouterLink expects an array, you will have to use simple URLs.

Consider your original snippet

<span *ngFor="#item of list">
    <a [href]="item.url">{{item.title}}</a> |
</span>

Assuming you're using HashLocationStrategy your URL should contain the hash

<span *ngFor="#item of list">
    <a [href]="'#/' + item.url">{{item.title}}</a> |
</span>

That should result in an URL like this

#/category2/987654/hello-world

Now that we have the URLs correctly formed, we can use the regex matchers we mentioned earlier

@RouteConfig([
  {
    name : 'ItemDetail',

    // regex that will match the URL in the href or the URL typed directly by the user
    regex : '^([a-z0-9]+)/([0-9]+)/([a-z\\-]+)$',

    // serializer is mandatory, but it is used when you have a routerLink with params
    serializer : (params) => {
      return new GeneratedUrl(`${params.a}/${params.b}/${params.c}`)
    },
    component : ItemDetail
  }
])

This is the easiest if you have pre-assembled URLs.

See this plnkr with an example working.

Note that regex matchers were introduced in beta.9 and they contain a few issues, see

  • https://github.com/angular/angular/issues/7602
  • https://github.com/angular/angular/issues/7554
  • https://github.com/angular/angular/issues/7531

You may found other ones.

I really apologize for my bad regex skills, probably you can bypass it, but hopefully you'll get the idea.

like image 39
Eric Martinez Avatar answered Sep 23 '22 12:09

Eric Martinez