[Angular] Add, Read, Detect Change and Preserve Query Parameters to URLs

Have you ever faced a need to pass some data between routes or pages in your Angular application? For example, while implementing pagination, filtering products by category, sorting a data table, and showing product details? In such situations, query parameters are the perfect solution for such situations! Query parameters allow us to optionally pass key-value data…

By.

min read

Have you ever faced a need to pass some data between routes or pages in your Angular application? For example, while implementing pagination, filtering products by category, sorting a data table, and showing product details? In such situations, query parameters are the perfect solution for such situations!

Query parameters allow us to optionally pass key-value data in the URL after a “?” question mark symbol in the URL of an application. They are useful especially when rendering dynamically changing data that a user sees on a page when navigated across the application.

In Angular, the Router module provides various methods to easily add, read, remove and manipulate query parameters from your application.

[lwptoc]

In this article, we will discuss everything to know how to work with query parameters in Angular. Let’s get started!

[Angular] Add, Read, Detect Change and Preserve Query Parameters to URLs

 

What are Query Parameters?

Query parameters are optional key-value pairs that can be appended to the end of a URL with a “?” question mark symbol. They allow us to pass data when navigating between routes and pages in our app.

This is how a URL with query params looks like:

yourdomain.com/path?key1=value1&key2=value2

The URLs with query params are quite useful when working with functionalities like Pagination, Filtering, Sorting, Passing IDs or tokens etc.

 

Adding Query Parameters

Angular provides an easy way to add query parameters when navigating between routes using the Router module. We just need to import the Router module into our component. Then we can start using its navigate method as shown below:

// Import the router
import { Router } from '@angular/router'; 

@Component({...})
export class ProductsComponent {

  constructor(private router: Router) {}

  // Navigate and add a query param
  goToPage(pageNum) {
    this.router.navigate(['products/phones'], {
      queryParams: { 
        page: pageNum  
      }
    });
  }
}

In the above snippet, you can notice how we are passing the page query param inside the queryParams object. Where pageNum is it a dynamic value? Similarly, we can pass any number of query parameters.

We can also prepare the query params object separately as a NavigationExtras object:

const queryParams: NavigationExtras = {
  queryParams: {
    page: pageNum 
  }
};

this.router.navigate(['products'], queryParams);

We can also remove the query param from the URL by passing null to its key, for example page: null will remove that query param from the URL.

 

Reading & Accessing Query Parameters

Once we have added some query parameters, we will see how to read these passed query params in our components.

We can use Angular’s ActivatedRoute service to fetch the query parameters from the URL. First, we import the ActivatedRoute and then subscribe to its queryParams observable or access its snapshot directly as shown below:

// Import ActivatedRoute
import { ActivatedRoute } from '@angular/router';

constructor(private route: ActivatedRoute) {}

ngOnInit() {

  // Subscribe to query params
  this.route.queryParams.subscribe(params => {
    console.log(params['page']);
  });

  // Access from snapshot
  const page = this.route.snapshot.queryParams['page']; 
}

 

We can also check if a given query param exists by using the hasOwnProperty method provided by the queryParams:

const hasPage = this.route.snapshot.queryParams.hasOwnProperty('page');

In this way, we can easily get the values of query params in a service or component class itself.

 

Handling Query Param Changes

Now that we know how to add and read query parameters, let’s check how to detect when the value of the query param changes. The Angular Router provides various events to which we can subscribe that will trigger to let us know when there is a change.

In this way, we can easily perform operations that are dependent on query parameter value changes. Let’s have an example on how to subscribe to query param value changes:

// Import Router 
import { Router } from '@angular/router';

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

  // Subscribe to events
  this.router.events.subscribe(event => {
    
    // Detect navigation end 
    if (event instanceof NavigationEnd) {
      
      // Get new query params  
      const page = this.route.snapshot.queryParams['page'];
      
      // React to query param changes
      this.getProducts(page); 
    }
  });
}

Here, we are subscribed to the router.events that will fire on every navigation. We are checking the NavigationEnd event and then fetching the new value of page using the snapshot.

 

Moreover, we can also subscribe to router events specifically for query param changes:

// Fires only when query params change
this.router.routerState.root.queryParams.subscribe(params => {
  // New params 
});

So router events allow us to properly respond when query parameters change in our Angular application.

 

Preserving Query Parameters

By default, query parameters will be removed when navigating to a new route. But often we want to preserve the current query params. For example, when implementing pagination, we want to maintain the current page when going between routes.

To do this, we can pass a queryParamsHandling option when navigating:

// Navigate and preserve current params
this.router.navigate(['products'], {
  queryParamsHandling: 'preserve' 
});

// Add new param but maintain existing
this.router.navigate(['products'], {
  queryParams: {page: 2},
  queryParamsHandling: 'preserve'
});

This will keep any existing query parameters intact. We can also merge new query params with existing ones using 'merge'.

So the queryParamsHandling option gives us a way to maintain query parameters across navigation in Angular. This helps create a seamless user experience.

 

Query Params vs. Route Params

In Angular, there are a couple of different ways to pass dynamic values in URLs – route parameters and query parameters. So how these two are different?

The main difference depends if the parameter is required or optional.

Route parameters are required values that are defined in advance in the route configuration:

// Route param 
{path: 'product/:id', component: ProductDetailComponent}

Query parameters are optional and can be added dynamically with the question mark “?”:

// Query param
/products?category=shoes

For example:

// Route param - product detail page 
{path: 'product/:id', component: ProductDetailComponent}

// Query param - filter products
/products?category=shoes&color=red

 

Conclusion

We discussed various aspects of query parameters in Angular applications. Query params provide an easy and flexible way to pass and read data that is getting passed between routes in Angulr applications.

Query parameters provide a simple but extremely useful way to pass optional data between routes in Angular applications.

So now you have all the knowledge needed to add flexible, dynamic navigation in your Angular apps using query parameters.

Leave a Reply

Your email address will not be published. Required fields are marked *