Introduction

Query parameters in Angular allow for passing optional parameters across any route in the application. Query parameters are different from regular route parameters, which are only available on one route and are not optional (e.g., /product/:id).
In this article, you will reference an example of an application that displays a list of products. You will provide optional order and price-range values that the receiving component can read and act on. The values provided will affect the ordering and filtering of the list of products.

Prerequisites

To follow through this tutorial, you’ll need:

Some familiarity with Angular Router and RouterLink and ActivatedRoute may be beneficial.

Using Query Parameters with Router.navigate

If you are navigating to the route imperatively using Router.navigate, you will pass in query parameters with queryParams.
In our example, if we want to route visitors to the products with the list ordered by popularity, it would look like this:

goProducts() {
  this.router.navigate(
    ['/products'],
    { queryParams: { order: 'popular' } }
  );
}

This will result in a URL that resembles:

http://localhost:4200/products?order=popular

You can also provide multiple query parameters. In our example, if we want to route visitors to the products with the list ordered by popularity and filtered with an expensive price range, it would look like this:

goProducts() {
  this.router.navigate(
    ['/products'],
    { queryParams: { order: 'popular', 'price-range': 'not-cheap' } }
  );
}

This will result in a URL that resembles:

http://localhost:4200/products?order=popular&price-range=not-cheap

Now, you have an understanding of how queryParams can be used to set query parameters.

Preserving or Merging Query Parameters with queryParamsHandling

By default, the query parameters are lost on any subsequent navigation action. To prevent this, you can set queryParamsHandling to either 'preserve' or 'merge'.
In our example, if we want to route visitors from a page with the query parameter { order: 'popular' } to the /users page while keeping the query parameters, we would use 'preserve':

goUsers() {
  this.router.navigate(
    ['/users'],
    { queryParamsHandling: 'preserve' }
  );
}

This will result in a URL that resembles:

http://localhost:4200/users?order=popular

In our example, if we want to route visitors from a page with the query parameter { order: 'popular' } to the /users page while passing the query parameter { filter: 'new' }, we would use 'merge':

goUsers() {
  this.router.navigate(
    ['/users'],
    {
      queryParams: { filter: 'new' },
      queryParamsHandling: 'merge' }
    );
}

This will result in a URL that resembles:

http://localhost:4200/users?order=popular&filter=new

Note: Preserving query parameters used to be achieved with preserveQueryParams set to true, but this is now deprecated in Angular 4+ in favor of queryParamsHandling.

Now, you have an understanding of how queryParamsHandling can be used to preserve and merge query parameters.

In our example, if instead, you are using the RouterLink directive to navigate to the route, you would use queryParams like this:

<a
  [routerLink]="['/products']"
  [queryParams]="{ order: 'popular'}"
>
  Products
</a>

And in our example, if you want to 'preserve' or 'merge' query parameters on subsequent navigation you would use queryParamsHandling like this:

<a
   [routerLink]="['/users']"
   [queryParams]="{ filter: 'new' }"
   queryParamsHandling="merge"
>
  Users
</a>

Now you understand how queryParams and queryParamsHandling can be used with RouterLink.

Accessing Query Parameter Values

Now that we know how to pass in optional query parameters to a route, let’s see how to access these values on the resulting routes. The ActivatedRoute class has a queryParams property that returns an observable of the query parameters that are available in the current URL.
Given the following route URL:

http://localhost:4200/products?order=popular

We can access the order query parameter like this:

// ...
import { ActivatedRoute } from '@angular/router';
import 'rxjs/add/operator/filter';

@Component({ ... })
export class ProductComponent implements OnInit {
  order: string;
  constructor(private route: ActivatedRoute) { }

  ngOnInit() {
    this.route.queryParams
      .filter(params => params.order)
      .subscribe(params => {
        console.log(params); // { order: "popular" }

        this.order = params.order;

        console.log(this.order); // popular
      }
    );
  }
}

In the console log, we would see the params object:

{ order: "popular" }

And the params.order value:

popular

There’s also queryParamMap, which returns an observable with a paramMap object.
Given the following route URL:

http://localhost:4200/products?order=popular&filter=new

We can access the query parameters like this:

this.route.queryParamMap
  .subscribe((params) => {
    this.orderObj = { ...params.keys, ...params };
  }
);

We used the object spread operator here, and this is the resulting shape of the data in orderObj:

{
  "0": "order",
  "1": "filter",
  "params": {
    "order": "popular",
    "filter": "new"
  }
}

Now, you have an understanding of how queryParams and queryParamMap can be used to access values on the resulting routes.

Conclusion

In this article, you used different examples to set and get query parameters in Angular. You were introduced to queryParams and queryParamsHandling with Router.navigate and RouterLink. You were also introduced to queryParams and queryParamMap with ActivatedRoute.
If you’d like to learn more about Angular, check out our Angular topic page for exercises and programming projects.