What is Routing in angular, what is it used for and why should you use it? This article will tell you all about it!
We use routing to separate different parts of our app, by using the URL to denote our location.
The idea is that we might put our comments page at the URL /comments and our posts page at /posts. In Angular, we’d have a CommentsComponent for the /comments page and a PostsComponent for the /posts page. In the common case, a router lets us map these URLs to a component.
There are three main components that we use to configure routing in Angular:
- Routes
- RouterOutlet which is a “placeholder” component that gets expanded to each route’s content
- RouterLink
Routes
To start explaining we will create new angular project and 3 components inside, easiest way to do is using terminal inside VS code. Go to app folder inside your application in terminal, create new folder called Components with “mkdir”, enter the folder and type following command:
“ng g c home” Here is the full command: ng generate component home, the “home” stands for component name. We do the same for posts and comments.
Home, Posts and Comments components.
Route is an object that we use on our application component that describes the routes we want to use. You can import them in your app.module.ts like so:
On top we need to import RouterModule for this to work:
import { RouterModule } from ‘@angular/router’;
In path you set the path of desired url for specific component, as you can see for our posts we will use PostsComponent and for comments we will use CommentsComponent.
To avoid errors and protect your app you should always add path with ** but make sure it’s in the last path you set, because if you set it before some other component you won’t be able to use that component’s path. Also with this we redirect the user to home if they type something random in url.
There is one crucial step you have to do for this to work now. In your main html page you need to include router-outlet, for this project it’s in app.component.html and we should add inside it.
Since we just created 3 components using ng we don’t have any data to return yet. For that we are going to create a service.
To make sure everything is working so far run “ng serve –open” which will start your default browser with application at localhost:4200. Now in url type /posts, full url should be like this:
localhost:4200/posts
If you get blank page with “posts works!” you did good job! Next step is to create a service.
In terminal navigate to “src” folder and with “mkdir” make new folder “services”. Navigate to services folder and run run: “ng g s posts” which will create new service for us. Inside our newly created service paste the following code:
import { Http } from '@angular/http'; import { Injectable } from '@angular/core'; import 'rxjs/add/operator/map'; @Injectable() export class FollowersService { url = 'https://jsonplaceholder.typicode.com/posts'; constructor(private http: Http) { } getPosts(){ return this.http.get(this.url).map(res => res.json()); } }
We are using JsonPlaceholder which is fake online REST API for testing. With it we get simple APIs, for example in our service we are going to get data using API from JsonPlaceholder and we are going to list that data in our angular app. You can observe this fake API as data coming from your back-end, from some database perhaps.
In our posts.component.ts we will write simple code to get all the posts from our service so first we declare new variable call it posts and set it to empty array. Then in ngOnInit we are calling our service and on subscribe telling it to populate our posts array with posts from fake API like so:
import { PostsService } from './../../../Services/posts.service'; import { Component, OnInit } from '@angular/core'; @Component({ selector: 'app-posts', templateUrl: './posts.component.html', styleUrls: ['./posts.component.css'] }) export class PostsComponent implements OnInit { posts = []; constructor(private service: PostsService) { } ngOnInit() { this.service.getPosts().subscribe(posts => this.posts = posts); } }
Finally in our posts.component.html we are going through all our posts with ngFor and listing only title and body of each post on our fake API.
<div class="row" *ngFor="let post of posts"> <div class="col-12"> <h3>{{post.title}}</h3> <p>{{post.body}}</p> <hr> </div> </div>
Now run ng serve if it’s not already running and in url navigate to /posts and you should see page like this:
This is not the whole page just the part of it.
Now we do the same for comments. Add new service, in the service’s url we set url from our fake API /comments. Then in our comments component we type almost identical code as for posts just change posts to comments.
API for comments is little different.It has 1 new property that posts didn’t have, email so in comments.component.html paste this code:
<div class="row" *ngFor="let comment of comments"> <div class="col-12"> <h3>{{comment.name}}</h3> <h4>{{comment.email}}</h4> <p>{{comment.body}}</p> <hr> </div> </div>
Router Link
To explain router link we will use what we have made so far and add few things. In our posts html component we are going to link title of each post so it is clickable and when u click it it redirect you to that post.
Now in our posts.service.ts we need to add a method to get only one post from our fake API.
getPost(postId){ return this.http.get(this.url + '/' + postId).map(res => res.json()); }
In app.module.ts we need to add another route path with one parameter ‘postId’ and it should look like this:
Finally, in our posts.component.ts we are going to have most changes so copy the code and we are going to explain what we added here:
import { PostsService } from './../../../Services/posts.service'; import { Component, OnInit } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; @Component({ selector: 'app-posts', templateUrl: './posts.component.html', styleUrls: ['./posts.component.css'] }) export class PostsComponent implements OnInit { posts = []; constructor(private service: PostsService, private route: ActivatedRoute) { } ngOnInit() { this.route.params.subscribe(p => { var postId = p['postId'] if (postId) this.service.getPost(postId).subscribe(posts => this.posts = [posts]) else this.service.getPosts().subscribe(posts => this.posts = posts) }) } }
In our constructor we are required to add ActivatedRoute and import it on the top. On ngOninit we are checking if our route parameters have postId and if it does we are going to show only that post by calling our method inside posts service that returns only one post by postId.
Otherwise we are going to return all the posts, meaning that there is no id inside our url.
Now when you run the application navigate to /posts and click on any post there, you should be redirected to that post.