Query parameters are an essential part of modern web development. They allow developers to pass additional information in the URL without modifying the actual route. This makes them particularly useful for search functionality, filtering data, pagination, or passing state between components. Angular provides a powerful mechanism for handling query parameters using the Router and ActivatedRoute services.
What are Query Parameters?
Query parameters are key-value pairs appended to a URL, usually after a ?
symbol. For example, in the URL:
/search?q=angular
- The path
/search
corresponds to the route. - The query parameter
q=angular
provides additional information to the component without changing the route itself.
Query parameters differ from route parameters (/user/:id
) in that route parameters are mandatory parts of the URL structure, whereas query parameters are optional and can be dynamically added or removed.
Adding Query Parameters in Angular
Angular provides the Router
service to navigate between routes programmatically. Query parameters can be added using the queryParams
option. Here’s a basic example:
import { Component } from '@angular/core';
import { Router } from '@angular/router';
@Component({
selector: 'app-search-button',
template: <button (click)="searchAngular()">Search Angular</button>
})
export class SearchButtonComponent {
constructor(private router: Router) {}
searchAngular() {
this.router.navigate(['/search'], { queryParams: { q: 'angular' } });
}
}
Explanation of the Code
- Router Service: Injected into the component constructor, the Router allows programmatic navigation.
- navigate() Method: Used to navigate to a specific route.
- queryParams Object: Contains the key-value pairs to append to the URL. In this example, the URL becomes
/search?q=angular
.
Accessing Query Parameters
Once query parameters are added to a URL, the target component can access them using the ActivatedRoute
service. This service provides a snapshot or an observable of the current route information.
Using snapshot
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
@Component({
selector: 'app-search',
template: <p>Search Query: {{ query }}</p>
})
export class SearchComponent implements OnInit {
query!: string;
constructor(private route: ActivatedRoute) {}
ngOnInit() {
this.query = this.route.snapshot.queryParamMap.get('q')!;
}
}
Using Observable queryParams
For dynamic query parameters that may change without reloading the component:
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
@Component({
selector: 'app-search',
template: <p>Search Query: {{ query }}</p>
})
export class SearchComponent implements OnInit {
query!: string;
constructor(private route: ActivatedRoute) {}
ngOnInit() {
this.route.queryParams.subscribe(params => {
this.query = params['q'];
});
}
}
Difference Between Snapshot and Observable
- Snapshot: Provides a static snapshot of the route at the time the component is initialized. If the query parameter changes later, the snapshot does not update automatically.
- Observable: Subscribing to
queryParams
allows the component to react to changes in the query parameters dynamically without reloading the component.
Multiple Query Parameters
Angular supports multiple query parameters in the URL. For example:
this.router.navigate(['/search'], { queryParams: { q: 'angular', page: 2, sort: 'asc' } });
Resulting URL:
/search?q=angular&page=2&sort=asc
In the component:
this.route.queryParams.subscribe(params => {
const searchQuery = params['q'];
const page = params['page'];
const sortOrder = params['sort'];
});
Combining Route Parameters and Query Parameters
It is possible to use route parameters and query parameters together. For example:
const routes: Routes = [
{ path: 'user/:id', component: UserComponent }
];
Navigating programmatically with query parameters:
this.router.navigate(['/user', 42], { queryParams: { ref: 'dashboard' } });
URL generated:
/user/42?ref=dashboard
Accessing in the component:
this.route.paramMap.subscribe(params => {
const userId = params.get('id');
});
this.route.queryParams.subscribe(params => {
const ref = params['ref'];
});
Preserving Query Parameters During Navigation
Sometimes, when navigating to another route, we may want to preserve existing query parameters. Angular provides the queryParamsHandling
option:
this.router.navigate(['/search'], { queryParamsHandling: 'preserve' });
preserve
: Keeps existing query parameters.merge
: Merges new query parameters with existing ones.
Example:
this.router.navigate(['/search'], { queryParams: { sort: 'desc' }, queryParamsHandling: 'merge' });
If the current URL is /search?q=angular
, the resulting URL will be:
/search?q=angular&sort=desc
Using Query Parameters in Links
Angular allows binding query parameters directly in templates using routerLink
:
<a [routerLink]="['/search']" [queryParams]="{ q: 'angular', page: 1 }">Search Angular</a>
Advantages
- Declarative syntax
- Easy to maintain in HTML templates
- Works seamlessly with Angular routing
Practical Example: Search and Filter
Imagine a search component with multiple filters:
import { Component } from '@angular/core';
import { Router } from '@angular/router';
@Component({
selector: 'app-filter-search',
template: `
<input [(ngModel)]="searchQuery" placeholder="Search">
<select [(ngModel)]="category">
<option value="all">All</option>
<option value="books">Books</option>
<option value="electronics">Electronics</option>
</select>
<button (click)="applyFilters()">Search</button>
`
})
export class FilterSearchComponent {
searchQuery: string = '';
category: string = 'all';
constructor(private router: Router) {}
applyFilters() {
this.router.navigate(['/search'], { queryParams: { q: this.searchQuery, cat: this.category } });
}
}
In the SearchComponent
:
this.route.queryParams.subscribe(params => {
const query = params['q'];
const category = params['cat'];
// Apply filtering logic here
});
Resulting URL example:
/search?q=angular&cat=books
Handling Optional Query Parameters
Query parameters are inherently optional. If a parameter is missing, Angular will return null
when accessed via snapshot
or undefined
via subscription:
const query = this.route.snapshot.queryParamMap.get('q'); // returns null if not present
This allows flexible component behavior depending on which query parameters are provided.
Query Parameters for Pagination
A common use case for query parameters is pagination. For example:
this.router.navigate(['/products'], { queryParams: { page: 3, size: 20 } });
In the component:
this.route.queryParams.subscribe(params => {
const page = +params['page'] || 1; // default to page 1
const size = +params['size'] || 10; // default size 10
this.loadProducts(page, size);
});
This ensures that the current page and page size are reflected in the URL and can be bookmarked or shared.
Query Parameters for Sorting
Similarly, sorting can be managed via query parameters:
this.router.navigate(['/products'], { queryParams: { sort: 'price', order: 'asc' } });
In the component:
this.route.queryParams.subscribe(params => {
const sortField = params['sort'] || 'name';
const sortOrder = params['order'] || 'asc';
this.sortProducts(sortField, sortOrder);
});
This approach allows multiple users to share the same sorting preferences via URL.
Query Parameters and Browser Refresh
Query parameters are part of the URL, so they persist even after the page is refreshed. This makes them ideal for scenarios where application state needs to survive page reloads.
Example:
- URL before refresh:
/search?q=angular&page=2
- After refresh: Angular automatically parses the query parameters, and the component reads them from
ActivatedRoute
.
Advantages of Using Query Parameters
- State Preservation: Query parameters allow preserving user state across routes.
- Dynamic Filtering: Useful for filtering, searching, and sorting data without modifying routes.
- Optional Parameters: Unlike route parameters, query parameters are optional and can be added or removed dynamically.
- Shareable URLs: Users can copy and share URLs that include query parameters for the same view.
- SEO Friendly: Query parameters are visible in the URL and can improve search engine indexing for dynamic content.
Leave a Reply