Mastering Angular 17 Routing
Tags: angular, frontend, routing
Published: 2024-05-06 05:32:05

Angular Routing is a fundamental feature that empowers developers to create dynamic and responsive Single Page Applications (SPAs). By seamlessly navigating between components, users experience a smooth and engaging interaction. In this guide, we’ll explore the key aspects of Angular Routing and how to leverage its capabilities effectively.

### Setting up routes
**1. Import Components:**

In the _**app.routes.ts**_ file, you import the components you just created. This allows you to reference these components while defining your routes

```
import { FirstComponent } from './first/first.component';
import { SecondComponent } from './second/second.component';
```
**2. Define Routes**

Create a **Routes** array in the same **app.routes.ts** file and define your routes. 
Each route is a JavaScript object containing a **path** (URL) and a **component**:

```
export const routes: Routes = [
    { path: 'first-component', component: FirstComponent },
    { path: 'second-component', component: SecondComponent}
];
```
**3. Configure Application**
Add the following configuration to the **app.config.ts file**:

```
import { routes } from './app.routes';

export const appConfig: ApplicationConfig = {
  providers: [provideRouter(routes)]
};
```
**4. Set Up Navigation**
In your application template (e.g., **app.component.html**), add navigation links for the two components:

```
<h1>Angular Router App</h1>
  <nav>
    <ul>
      <li><a routerLink="first-component" routerLinkActive="active">First Component</a></li>
      <li><a routerLink="second-component" routerLinkActive="active">Second Component</a></li>
    </ul>
  </nav>

  <!-- The routed views render on <router-outlet> -->
  <router-outlet></router-outlet>
```
You also need to add the **_RouterLink_**, **_RouterLinkActive_**, and **_RouterOutlet_** to the imports array of AppComponent.

‘**routerLink**’ can also take an array of route segments, allowing you to navigate to routes with dynamic values.

```
<a [routerLink]="['/products', productID]">View Product</a>
```
In this case, **productId** is a variable representing the specific product ID, and clicking the link navigates to the product detail page with the corresponding ID.

Additionally you can set up navigation using **Router.navigate**

```
constructor(private router: Router) {}

goToItems() {
  this.router.navigate(['/items']);
}
```
If your route requires parameters, you can include them in the navigation array.

```
goToItemDetails(itemID: number) {
  this.router.navigate(['/items', itemID]);
}
```
You also need to add Router to the imports array of **AppComponent**

**5. Route Order**
The Router uses a first-match-wins strategy, so list more specific routes first, followed by an empty path route as the default. The wildcard route should come last.

**6. Redirects**
Implement redirects by configuring a route with **redirectTo** and **pathMatch**. For example:

```
{ path: '', redirectTo: '/home', pathMatch: 'full' },
```
Ensure that redirect routes are placed before wildcard routes in your configuration.

**7. Displaying a 404 page**
If you want to display a custom 404 page, set up a wildcard route with the component property set to the **PageNotFoundComponent**:

```
{ path: '**', component: PageNotFoundComponent },
```
**8. Nesting Routes**
As your application grows, consider creating child routes relative to a component. These are called child routes. Include a second **<router-outlet>** in your parent component template and define child routes in the Routes array:

```
const routes: Routes = [
    {
        path: 'parent',
        component: ParentComponent,
        children: [
        { path: 'child1', component: Child1Component },
        { path: 'child2', component: Child2Component },
        // Add more child routes as needed
        ]
    }
];
```
**9. Setting Page Titles**
Assign unique titles to pages using the title property in the route configuration. For example:

```
const routes: Routes = [
    {
        path: 'parent',
        title: 'Parent',
        component: ParentComponent,
        children: [
        { path: 'child1', title: 'Child1', component: Child1Component },
        { path: 'child2', title: 'Child2', component: Child2Component },
        // Add more child routes as needed
        ]
    }
];
```
**10. Getting router information**
Let’s consider an example where we have a list of blog posts, and we want to navigate to a detailed view of a specific post. The detailed view should receive the post ID from the route to display the correct information. Here’s how you can achieve this:

In this example, we’ve set up routes to navigate from the list of blog posts to the details of a specific post. The **BlogDetailComponent** uses the **@Input** property **postId** to receive the ID from the route, fetches the details using the **BlogService**, and displays the information.

In your application’s routing configuration, use the **withComponentInputBinding** feature with the **provideRouter** method. This allows you to pass information from one component to another through the route.

```
import { ApplicationConfig } from '@angular/core';
import { provideRouter, withComponentInputBinding } from '@angular/router';

import { appRoutes } from './app.routes'; 

export const appConfig: ApplicationConfig = {
  providers: [provideRouter(appRoutes, withComponentInputBinding())]
};
```
In your **BlogListComponent**, when a user clicks on a blog post to view details, navigate to the **blog/:postId** route:

```
viewBlogDetails(postId: string) {
    this.router.navigate(['/blog', postId]);
  }
```
In the component where you want to receive the information, define an **@Input()** property that matches the name of the parameter you want to receive

```
export class BlogDetailComponent {
  @Input() set postId(postId: string) {
    this.post$ = this.blogService.getBlogPost(postId);
  }

  post$!: Observable<BlogPost | undefined>;

  constructor(private blogService: BlogService) {}
}
```
To get the rest of the code check the following links:
[https://github.com/anthony-kigotho/blog](https://github.com/anthony-kigotho/blog)