How to Get Params from URL in Angular 17 Component

In this tutorial, we'll see how to get params from URL in Angular 17. Understanding this we'll be helpful in all versions of Angular like Angular 18. There are two ways, the old way which employs the Router APIs such as the ActivatedRoute service to get parameters from a URL and the modern approach that directly uses the @Input decorator.

We are going to learn about these topics:

  • How to set up parameterized routes in our route configuration object.
  • How components can be informed about the parameter values when the URL is accessed.

Table of Contents:

  1. Understanding URLs and Parameters
  2. Why URL Parameters Are Used
  3. Using the ActivatedRoute Service to get URL Parameters
  4. Example Getting URL Parameters in Angular Component
  5. How to Get Parameters using Snapshot
  6. Binding URL Parameters to @Input Properties
  7. Step by Step Example
  8. Conclusion

In angular, we can distinguish two types of URL:

  1. URL pattern /products/:length. For example: /products/10: In this case, you can get raw value by using route.snapshot.paramMap.get or subscribe to the route.paramMap Observable to get the URL parameters
  2. URL pattern /products?length=value. For example: /products?length=10. In this case, you can get the raw value with route.snapshot.queryParamMap.

Understanding URLs and Parameters

Oftentimes we need a variable as part of the path in one or more of our routes (URLs), such as an ID.

Assuming that we maintain a customer list and each customer has an ID, the URLs for each customer may look like:

/customer/1
/customer/2
/customer/3
[...]

Now we need to write a route for each URL parameter as follows:

const routes: Routes = [
 { path: 'customer/1', component: CustomerComponent },
 { path: 'customer/2', component: CustomerComponent },
 { path: 'customer/3', component: CustomerComponent }
];

However, the more effective approach is to set up one route with one component named CustomerComponent, which receives the numerical part of the URL.

That is called a parameterized route, and we can implement in Angular it as follows:

const routes: Routes = [
 { path: 'customer/:id', component: CustomerComponent }
];

The route contains a variable called id, which we know is a variable because it starts with a colon :. Now before we can see how to get the id parameter from the URL in the component, let's first see why URL parameters are used.

Why URL Parameters Are Used

URL parameters are a crucial component of web development, providing scalability and functionality in a wide range of applications. Here are a few key explanations why URL parameters are used:

URL parameters enable developers to generate content that is dynamic. Instead of static pages, content can be generated using URL parameters. This strategy is frequently utilized in:

  • Routing: Use parameters, such as /product/:id, to build dynamic routes based on user input or data.
  • Personalization: The process of serving different material to users based on their preferences or other criteria.
  • Deep Links: URLs with parameters can deep-link to specific parts of an application or website.
  • Resource Identification: Path parameters identify specific resources on the server (e.g., /users/123).

Now that we've seen why URL parameters are used, let's see how to use the ActivatedRoute service to get URL parameters in Angular.

Using the ActivatedRoute Service to get URL Parameters

In most cases, you need to start by injecting the ActivatedRoute service to get URL parameters either via constructor or using the inject() method.

Note: In Angular, most often you can use the ActivatedRoute service to get parameters from a URL. You can extract both route parameters (e.g., from /customers/:id) and query parameters (e.g., from /customers?perPage=10).

With this core Angular service, you are offered three ways to get your route parameters.

  • Snapshot: The initial choice is to use the snapshot object. As the name implies, it enables you to capture a snapshot of the route state and access it to get URL parameters and queries.
  • The paramMap Observable: by subscribing to this Observable we get an object that contains all of our URL parameters.
  • Observables: As an alternative, each parameter can be treated as an observable. even though this may appear more complicated, it offers the benefit of being informed when the value changes.

Note: Employing the snapshot object returns static values, which means that if the parameters change, you will not be informed unless you refresh the component. It is generally recommended to choose the Observable option.

Example Getting URL Parameters in Angular Component

Let's take this example. Let's suppose you are developing an Angular 17 application with a ProductComponent that shows details about a particular product. The product data will be fetched using a product ID from the route URL:

import { Component, OnInit, inject } from '@angular/core';
import { ActivatedRoute } from '@angular/router';

@Component({
  selector: 'app-product',
  template: '<div>Product ID: </div>',
})
export class ProductComponent implements OnInit {

  private route = inject(ActivatedRoute);
  productId!: string;

  constructor(private route: ActivatedRoute) {}

  ngOnInit() {
    this.route.paramMap.subscribe((params) => {
      this.productId = params.get('productId')!;
    });
  }
}

In the src/app/app.routes.ts file, the route with the parameter should be like the following:

import { Routes } from '@angular/router';
import { ProductComponent } from './pages/product/product.component';
export const routes: Routes = [
    {
        { path: 'product/:productId', component: ProductComponent }
    }
];

So we simply inject the ActivatedRoute service as route and subscribe to its paramMap property which is an observable then we use the get() method to get the URL parameters called productId:

this.productId = params.get('productId')!;

How do we know the name of the URL parameter?

By simply looking at the route configuration of the URL pointing the component. It's the name passed after to colon in this example the URL parameter is productId.

Moreover, you may also pass any required value via the data property inside the Route configuration in Angular routing as the following:

{ path: 'product/:productId', component: ProductComponent, data: { role: 'user',} }

We can also get the URL parameter by using the map() operator and subscribing directly to the parameter Observable as follows:

import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';

@Component({
  selector: 'app-product',
  template: `
    <div>
      Product ID: 
    </div>
  `,
})
export class ProductComponent implements OnInit {
  productId$: Observable<string | undefined>;

  constructor(private route: ActivatedRoute) {
    // Getting a parameter from the route (e.g., from `/product/:productId`)
    this.productId$ = this.route.params.pipe(map((params) => params['productId']));
  }

  ngOnInit() {
    this.productId$.subscribe((id) => {
      console.log(`Product ID: ${id}`);
    });
  }
}

By employing observables, you may subscribe to these streams (via AsyncPipe or subscribe function) get updates anytime the parameter values change.

This enables greater flexibility and responsive behavior in your components.

How to Get Parameters using Snapshot

We can use another way to get the URL parameters without using Observables. Here is the code:

import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';

@Component({
  selector: 'app-product',
  template: '<p>Product ID: </p>',
})
export class ProductComponent implements OnInit {
  productId!: number; // Using '!' to indicate it will be initialized

  constructor(private route: ActivatedRoute) {}

  ngOnInit() {
    const id = this.route.snapshot.paramMap.get('productId'); // Get the route parameter
    if (id) {
      this.productId = +id; // Convert to number
    }
  }
}

snapshot.paramMap provides a snapshot of the current route's parameters. Use .get('productId') to retrieve a specific parameter.

Now that we've seen how to get URL parameters using the ActivatedRoute, let's see how to use the @Input decorator in Angular 16+ to achieve the same goals.

Binding URL Parameters to @Input Properties

Beginning with Angular 16, we may bind URL parameters and query strings to component @Input() attributes without injecting the ActivatedRoute service. This allows it to get to route information in your components while reducing the length of code you need to produce.

Angular v16 came out with many new features aimed at improving the developer experience (DX). One of these capabilities is Router Input, that enables you to get to route information using inputs.

The first step, is to inform Angular that we intend to utilize input properties to get route parameters. We do this during the application configuration.

The method we employ to accomplish this is determined by the type of bootstrapping used by our application.

Using standalone component bootstrapping, we may bootstrap an application in this way:

import { bootstrapApplication } from '@angular/platform-browser';
import { appConfig } from './app/app.config';
import { AppComponent } from './app/app.component';

bootstrapApplication(AppComponent, appConfig)
  .catch((err) => console.error(err)); 

To use Router Inputs, change your route provider in the ./app/app.config.ts file as follows:

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

import { provideHttpClient } from '@angular/common/http';
import { routes } from './app.routes';

export const appConfig: ApplicationConfig = {
  providers: [
    provideHttpClient(),
    provideRouter(routes, withComponentInputBinding())
  ]
};

We pass the call to withComponentInputBinding to provideRouter() the to enable automatic binding of route parameters to component inputs.

If you are still using NgModules to bootstrap your Angular application, you need to use something like this:

import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { ProductComponent } from './product/product.component';

const routes: Routes = [
  { path: 'products/:id', component: ProductComponent } // Define the route with a path parameter
];

@NgModule({
  imports: [RouterModule.forRoot(routes, { bindToComponentInputs: true })], // Enable binding with 'bindToComponentInputs'
  exports: [RouterModule]
})
export class AppRoutingModule { }

In RouterModule.forRoot(), we set bindToComponentInputs to true to indicate to Angular 16+ that we intend to read route parameters via input properties.

Just like the withComponentInputBinding example, the bindToComponentInputs option in RouterModule.forRoot instructs Angular 16+ to implicitly bind route parameters to component inputs with matching names.

We have now provided automatic route parameter mapping using input properties. We can now use a simpler way to get URL parameters in Angular.

With the configured route provider, you can currently watch the route parameters to get their values through input bindings in your component. For example, in our previous component, we can get the value of the URL parameter called productId using the following line:

@Input() productId: string = '';

That's it to get the URL parameter, you simply declare a component member with the same name as the parameter (In the URL) and decorate it with the @Input decorator. Remember this is only valid in Angular 16+.

If the productId parameter changes, your component will be informed (via the Observable).
Router Inputs are available only from the routed component. If you need to get to these parameters in a child component, you may employ one of the ways indicated above or send the input via input binding between the parent and child components.

We can give the input property the same name as the route parameter, which in this case is productId. Because route parameters are strings, we assign an empty string as the initial value.

We can use an alternative property name, for example, id. However, we need to supply the route parameter name to the @Input() decorator, as the following:

@Input('productId') id: string = '';

When the route is active (for example, by browsing to http://localhost:4200/product/123), Angular receives the product details using the id value (123) and assigns them to the ProductComponent's productId property.

How to Get Route Parameters from URL in Angular 17: Step by Step

To demonstrate how to get parameters from URL in Angular 17, let's create a step by step example.

As a prerequisite, you should have Node.js and Angular CLI installed on your development machine.

Open a new terminal and run the following command to create an Angular 17 project:

ng new angularrouteparams

Choose CSS as the stylesheet format and N for Do you want to enable Server-Side Rendering (SSR) and Static Site Generation (SSG/Prerendering)? (y/N).

After installing the packages, navigate to your Angular project and serve it using:

cd angularrouteparams
ng serve

You'll be able to access your Angular 17 app from http://localhost:4200/. Now let's see how to get parameters from URL.

Create a src/app/customer.ts file and add the following class that holds information about a single customer that will be retrieved from URL by its ID:

export class Customer {
    customerId: number;
    name: string;

    constructor(customerId: number, name: string){
        this.customerId = customerId;
        this.name = name;
    }
}

Next, use the following command to create a customer details component which will be responsible for getting the customer ID from the URL and display it:

 ng g c customer-detail

Open the src/app/app.routes.ts file and add a route with two parameters:

import { Routes } from '@angular/router';
import { CustomerDetailComponent } from './customer-detail/customer-detail.component';

export const routes: Routes = [
    {
        path: 'customer-detail/:customerId/:customerName', 
        component: CustomerDetailComponent, 
        pathMatch:'full'
    }
];

This route accepts two URL parameters customerId and customerName. All we can do to get these params in our customer component is to enable component input binding by going to the src/app/app.config.ts file and update it as follows:

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

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

export const appConfig: ApplicationConfig = {
  providers: [provideRouter(routes, withComponentInputBinding())]
};

We simply pass the call to withComponentInputBinding() as a second parameter to provideRouter().

Now we can get these parameters in the customer component by using them with the @input decorator. Open the src/app/customer-detail/customer-detail.component.ts file and update it as follows:

import { Component, Input } from '@angular/core';

@Component({
  selector: 'app-customer-detail',
  standalone: true,
  imports: [],
  templateUrl: './customer-detail.component.html',
  styleUrl: './customer-detail.component.css'
})
export class CustomerDetailComponent {
  @Input() customerId = '';
  @Input() customerName = '';
}

Open the src/app/customer-detail/customer-detail.component.html file and update it as follows to display the URL parameters:

<h3>Selected Customer #</h3>
<p>
    Name: 
</p>

Now open the src/app/app.component.ts and update it as follows:

import { Component } from '@angular/core';
import { RouterModule, RouterOutlet } from '@angular/router';
import { Customer } from './customer';

@Component({
  selector: 'app-root',
  standalone: true,
  imports: [RouterOutlet, RouterModule],
  templateUrl: './app.component.html',
  styleUrl: './app.component.css'
})
export class AppComponent {
  title = 'angularrouteparams';

  public customers: Array<Customer> = [
    new Customer(1, 'John Doe'),
    new Customer(2, 'Jane Smith'),
    new Customer(3, 'Robert Johnson'),
    new Customer(4, 'Emily Davis'),
    new Customer(5, 'Michael Brown'),
  ]; 
}

Notice that we've imported the router module in this standalone component to be able to use routeLink in the corresponding template. Open the src/app/app.component.html and change it as follows:

<h1>Customer List</h1>
<div>
    <table class='table'>
        <thead>
            <tr>
                <th>ID</th>
                <th>Name</th>
            </tr>
        </thead>
        <tbody>
          @for(customer of customers; track customer.customerId){
            <tr>
                <td></td>
                <td><a [routerLink]="['/customer-detail',customer.customerId, customer.name]"> </a> </td>
            </tr>
          }
        </tbody>
    </table>
    <router-outlet></router-outlet>
</div>

This code creates a table that displays a list of customers and sets up links to navigate to a customer detail. The <tbody> section contains the table rows that represent the data. The @for loop (in Angular 17) iterates over the customers array to generate rows dynamically. The [routerLink] directive creates a navigation link to another route. In this case, the route is /customer-detail, with customer.customerId and customer.name as route parameters. The [routerLink] directive creates links for navigation, allowing users to click on a customer name to view more details. The <router-outlet></router-outlet> serves as a placeholder for dynamically loaded content based on Angular's routing configuration. When you navigate to a different route, the content corresponding to that route is displayed within the router-outlet.

Conclusion

In this article, you were introduced to different ways you can get parameters from an URL in Angular:

  1. Using ActivatedRoute to get path and query parameters.
  2. Binding parameters with @Input decorators, which offers a cleaner and simpler approach in Angular 16 and beyond.

Beginning with Angular v16+, we may get route parameters from a URL through an input property defined with the @Input() decorator in the component mapped to the path containing the URL parameter. This results in a simpler and quicker syntax to get URL params. We have no more need to use Angular's Activated Route service.