Angular Router: Query Parameters

Query parameters in Angular allow for passing optional parameters across any route in the application. Query params are different from regular route parameters, which are only available on one route and are not optional (e.g.: /product/:id). Let’s see how to work with query parameters.

Let’s use a very simple example where we want to route to a path an provide optional order and price-range values that the receiving component can read and act on if available to order and filter a list of products.

Query Params With Router.navigate

If you are navigating to the route imperatively using Router.navigate, here’s how to pass-in query params:

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

This will result in a url that looks like this:

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

You can also provide multiple query params like this:

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

And the url looks like this:

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

Preserve or Merge Query Params 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. Let’s say we are on the products route and want to route the user to the users page while keeping the query params:

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

We can use merge instead of preserve if you’re also passing new query params to the users route:

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

The resulting URL:

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

Preserving query params used to be done with preserveQueryParams set to true, but this is now deprecated in Angular 4+ in favor of queryParamsHandling.

If instead you are using the RouterLink directive to navigate to the route, here’s how you would set query params:

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

And if you want to preserve or merge query params on subsequent navigation:

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

Accessing Query Param 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 param 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
      });
  }
}

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
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"
  }
}
✖ Clear

🕵 Search Results

🔎 Searching...