Query parameters are a key part of web application URLs, allowing developers to pass additional information between views without changing the main route. In Angular, accessing query parameters in a component is straightforward and extremely useful for building dynamic applications, such as search functionality, filtering lists, and displaying content conditionally.
This article explores how to read query parameters in Angular, with detailed examples, best practices, and advanced usage.
Introduction to Query Parameters
A URL often contains query parameters to pass information:
https://example.com/products?q=laptop&category=electronics
q=laptop
is a query parameter for a search term.category=electronics
is another query parameter specifying a product category.
Query parameters differ from route parameters:
- Route parameters are part of the URL path (e.g.,
/user/1
). - Query parameters are optional and follow the
?
symbol.
Angular provides the ActivatedRoute
service to access query parameters easily.
Setting Up Angular for Query Parameters
To demonstrate query parameter handling, let’s create a simple Angular application with a search functionality.
- Create a new Angular project:
ng new angular-query-demo
cd angular-query-demo
- Generate components:
ng generate component search
ng generate component results
- Configure routes:
Open app-routing.module.ts
:
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { SearchComponent } from './search/search.component';
import { ResultsComponent } from './results/results.component';
const routes: Routes = [
{ path: '', component: SearchComponent },
{ path: 'results', component: ResultsComponent }
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
Using Query Parameters in Angular
Angular uses the ActivatedRoute
service to provide access to query parameters.
Basic Example
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
@Component({
selector: 'app-results',
template: <p>Search query: {{ query }}</p>
})
export class ResultsComponent implements OnInit {
query: string | null = '';
constructor(private route: ActivatedRoute) {}
ngOnInit(): void {
this.route.queryParamMap.subscribe(params => {
this.query = params.get('q');
console.log(this.query);
});
}
}
queryParamMap
is an observable that contains all query parameters.params.get('q')
retrieves the value of the query parameter namedq
.- Using
.subscribe()
ensures the component reacts to changes in query parameters dynamically.
Passing Query Parameters via routerLink
To use query parameters, you can pass them in the template using [queryParams]
with routerLink
.
<a [routerLink]="['/results']" [queryParams]="{ q: 'laptop' }">Search Laptop</a>
<a [routerLink]="['/results']" [queryParams]="{ q: 'phone' }">Search Phone</a>
Clicking these links navigates to /results?q=laptop
or /results?q=phone
without reloading the page.
Query Parameters in Forms
Search functionality often comes from a form input. Angular allows binding form values to query parameters.
Example: Search Form
<form (submit)="search(searchInput.value)">
<input #searchInput type="text" placeholder="Enter search term">
<button type="submit">Search</button>
</form>
import { Component } from '@angular/core';
import { Router } from '@angular/router';
@Component({
selector: 'app-search',
templateUrl: './search.component.html'
})
export class SearchComponent {
constructor(private router: Router) {}
search(query: string) {
this.router.navigate(['/results'], { queryParams: { q: query } });
}
}
- The
Router.navigate()
method accepts aqueryParams
object. - Users can type a search term, and the query parameter updates dynamically.
Multiple Query Parameters
Query parameters can include multiple values.
this.router.navigate(['/results'], {
queryParams: { q: 'laptop', category: 'electronics', sort: 'price' }
});
In the component:
ngOnInit(): void {
this.route.queryParamMap.subscribe(params => {
const query = params.get('q');
const category = params.get('category');
const sort = params.get('sort');
console.log(query, category, sort);
});
}
This allows creating rich and dynamic filters in applications.
Handling Changes in Query Parameters
Query parameters can change without navigating to a new route. For example, users might change a filter dynamically.
Angular’s queryParamMap
observable ensures components react to changes in real-time.
ngOnInit(): void {
this.route.queryParamMap.subscribe(params => {
this.query = params.get('q');
this.category = params.get('category');
this.applyFilters();
});
}
applyFilters() {
console.log('Filters applied:', this.query, this.category);
}
Using queryParamsHandling
for Navigation
When navigating programmatically, you might want to preserve existing query parameters.
this.router.navigate(['/results'], {
queryParams: { page: 2 },
queryParamsHandling: 'merge'
});
'merge'
preserves existing parameters and adds new ones.'preserve'
keeps all current query parameters without changes.
Reading Query Parameters with snapshot
If you only need the query parameters once, you can use ActivatedRoute.snapshot.queryParamMap
.
ngOnInit(): void {
const query = this.route.snapshot.queryParamMap.get('q');
console.log('Snapshot query:', query);
}
snapshot
is not reactive.- It’s faster for one-time reads but won’t update if parameters change.
Query Parameters with Angular Forms
You can bind Angular Reactive Forms or Template-driven Forms to query parameters for enhanced search experiences.
Reactive Form Example
import { Component, OnInit } from '@angular/core';
import { FormControl } from '@angular/forms';
import { Router, ActivatedRoute } from '@angular/router';
@Component({
selector: 'app-search',
template: `
<input [formControl]="searchControl" placeholder="Search">
`
})
export class SearchComponent implements OnInit {
searchControl = new FormControl('');
constructor(private router: Router, private route: ActivatedRoute) {}
ngOnInit(): void {
this.route.queryParamMap.subscribe(params => {
this.searchControl.setValue(params.get('q'));
});
this.searchControl.valueChanges.subscribe(value => {
this.router.navigate([], { queryParams: { q: value }, queryParamsHandling: 'merge' });
});
}
}
- This keeps the input field synchronized with query parameters.
- Changes in the input update the URL dynamically without page reload.
Best Practices for Query Parameters
- Use Observables for Dynamic Data: Subscribe to
queryParamMap
for real-time updates. - Preserve Query Parameters When Necessary: Use
queryParamsHandling: 'merge'
. - Use Meaningful Parameter Names: Avoid cryptic names like
?a=1
. - Combine with Route Guards: Validate query parameters when necessary.
- Avoid Overusing Query Parameters: Use them for filtering and dynamic content, not for essential navigation paths.
Real-World Use Cases
- Search Pages:
/products?q=laptop
- Users can filter and search products dynamically.
- Pagination:
/products?page=2&size=10
- Controls page number and size of results dynamically.
- Sorting and Filtering:
/products?category=electronics&sort=price
- Filter and sort content without reloading the page.
- Dynamic Forms:
- Populate forms based on query parameters for better user experience.
Complete Example
<!-- search.component.html -->
<form (submit)="search(searchInput.value)">
<input #searchInput type="text" placeholder="Search term">
<button type="submit">Search</button>
</form>
// search.component.ts
import { Component } from '@angular/core';
import { Router } from '@angular/router';
@Component({
selector: 'app-search',
templateUrl: './search.component.html'
})
export class SearchComponent {
constructor(private router: Router) {}
search(query: string) {
this.router.navigate(['/results'], { queryParams: { q: query } });
}
}
// results.component.ts
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
@Component({
selector: 'app-results',
template: <p>Search query: {{ query }}</p>
})
export class ResultsComponent implements OnInit {
query: string | null = '';
constructor(private route: ActivatedRoute) {}
ngOnInit(): void {
this.route.queryParamMap.subscribe(params => {
this.query = params.get('q');
console.log(this.query);
});
}
}
This example demonstrates a fully functional query parameter-based search system in Angular.
Leave a Reply