Angular2 Villain Deep Routing (Part 3)

Jonas Felix
letsboot
Published in
3 min readOct 13, 2016

Using CLI, Webpack and Github Pages.

The Angular2 Villains tutorial using angular-cli and webpack from the start.

Check out our Angular in-house trainings or a public Angular courses.
Try out fossilo.com, our angular project to archive complete websites.

If you have any inputs or improvements please fork, fix and add a pull request: https://github.com/wingsuitist/villains/

11. Parameterized route

The router is also able to use parameters to enable linking directly to a record:

villain/23

In our example we want to link to the VillainListComponent which then selects and shows the villain with the provided id.

11.2. Add the route

To enable the route we only have to add it tou our app.rougint.ts:

{
path: 'villain/:id',
component: VillainListComponent
},

This only maps this route to the VillainListComponent. We can already call it now, but it won’t make any use of the idparameter.

11.3. Get villain by id

Before we want to use the id, we need a possibility to get the villain by id. This is a task that belongs to thevillain.service.ts:

getVillain(id: number): Villain {
let villains = this.getVillains();
return villains.find(villain => villain.id === id);
}

11.4. Use the id parameter

To use the id parameter we need to get in the VillainListComponent using the router in villain-list.component.ts:

//...
import { ActivatedRoute, Params } from '@angular/router';
import { Location } from '@angular/common';
//...
export class VillainListComponent implements OnInit {
//...
constructor(
private villainService: VillainService,
private route: ActivatedRoute,
private location: Location) {}
//...

And next we get the matching villain on initialization if we got an id by the ActivatedRoute object:

ngOnInit(): void {
this.villains = this.villainService.getVillains();
this.route.params.forEach((params: Params) => {
let id = +params['id'];
this.villain = this.villainService.getVillain(id);
});
}

As we use the existing villain property of our VillainListComponent it will work out of the box. Now it’s already possible to call the URL using in example http://localhost:4200/villain/23.

11.4. Linking to a the villains

Now we can make use of this and link to the villains. For example we could enable the user to open a villain directly from the power component in owers.component.html:

<li *ngFor="let villain of villains">
<a (click)="chooseVillain(villain)">
{{villain.alias}}
</a>
(<a target="_blank" routerLink="/villain/{{villain.id}}">peak</a>)
</li>

This would enable the player to peak into the villain in a new window. Thanks to the routerLink attribute, we can directly link to the matching villain.

But we could also change our list to use links instead of the internal onSelect() function. For that we remove the (click)event from the list element and instead add proper <a> link tags:

<ul class="thisVillain">
<li *ngFor="let thisVillain of villains"
[class.selected]="thisVillain === villain">
<a routerLink="/villain/{{thisVillain.id}}">
{{thisVillain.alias}}
<span class="power">({{thisVillain.power}})</span>
</a>
</li>
</ul>

This allows us to remove the onSelect function in villain-list.component.ts.

And to improve the look at least a little bit we can add this to our villain-list.component.css:

a {
text-decoration: none;
}
.selected a {
text-decoration: underline;
}

Defining the style of the <a> tag seams strange, as we don’t want to change the looks globally. But thanks to Angular the css styles of our component only apply to the template of this component. This makes sure that we are not interfering with any other elements and improves modularity for reuse in other applications.

11.5. Using routes in functions

We can also call routes from within our components. One simple example is to provide a back link, which basically calls the regular browser back link:

goBack(): void {
this.location.back();
}
<button (click)="goBack()">Back</button>

Another example is to actually call a specific route from within a components class:

gotoVillain(villain: Villain): void {
let link = ['/villain', villain.id];
this.router.navigate(link);
}

To do this you need to inject the router into your component class:

import { Router } from '@angular/router';
//...
constructor(
private router: Router,
//...

--

--

Jonas Felix
letsboot

Full Stack Entrepreneur - on a creative journey after first successful exit. New tech, science, OpenSource, Software Development, Space Enthusiast, Skydiver...