Как получить параметры запроса (query parameters) из URL в Angular 5?
Решение: используем ActivatedRoute и Observable
В Angular маршрутизация построена на реактивном подходе, поэтому параметры запроса приходят в виде Observable. Это сделано для того, чтобы компонент мог реагировать на изменения URL без перезагрузки страницы. Давайте разберем пошагово, как правильно получить значения.
Шаг 1: Импортируйте необходимые модули.
Убедитесь, что в вашем AppModule импортирован RouterModule:
// app.module.ts
import { RouterModule } from '@angular/router';
@NgModule({
imports: [
RouterModule.forRoot([
{ path: 'products', component: ProductsComponent }
])
]
})
export class AppModule { }
Шаг 2: Правильно используйте ActivatedRoute в компоненте.
В вашем компоненте нужно подписаться на Observable queryParams:
// products.component.ts
import { Component, OnInit, OnDestroy } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { Subscription } from 'rxjs';
@Component({
selector: 'app-products',
templateUrl: './products.component.html'
})
export class ProductsComponent implements OnInit, OnDestroy {
category: string;
page: number;
private querySubscription: Subscription;
constructor(private route: ActivatedRoute) { }
ngOnInit() {
// Подписываемся на изменения query parameters
this.querySubscription = this.route.queryParams.subscribe(params => {
this.category = params['category'];
this.page = +params['page']; // Преобразуем строку в число с помощью '+'
console.log('Category:', this.category);
console.log('Page:', this.page);
});
}
ngOnDestroy() {
// Важно! Отписываемся от подписки, чтобы избежать утечек памяти
if (this.querySubscription) {
this.querySubscription.unsubscribe();
}
}
}
Шаг 3: Альтернативный метод — snapshot (если параметры не меняются).
Если вы уверены, что URL не будет изменяться динамически (например, пользователь не будет менять параметры через навигацию на той же странице), можно использовать более простой вариант:
ngOnInit() {
const params = this.route.snapshot.queryParams;
this.category = params['category'];
this.page = +params['page'];
console.log('Category:', this.category);
console.log('Page:', this.page);
}
Объяснение:
- Observable vs Snapshot: Observable (
queryParams) — это поток данных, который обновляется при каждом изменении URL. Snapshot (route.snapshot.queryParams) — это моментальный снимок, который берется один раз при инициализации компонента. - Преобразование типов: Все параметры из URL приходят как строки. Если вам нужно число (например, номер страницы), используйте
+params['page']илиNumber(params['page']). - Отписка: Если используете Observable, обязательно отписывайтесь в
ngOnDestroy, иначе подписка останется висеть и может вызвать утечку памяти.
Проверка в шаблоне:
<!-- products.component.html -->
<h2>Товары</h2>
<p>Категория: {{ category }}</p>
<p>Страница: {{ page }}</p>
Теперь при переходе по URL /products?category=electronics&page=2 вы увидите в консоли и на странице соответствующие значения.
Альтернативный подход: использование RouterLink и сервиса Params
Если вам нужно получать параметры в нескольких компонентах или вы предпочитаете более декларативный подход, можно создать отдельный сервис для работы с query-параметрами:
// query-params.service.ts
import { Injectable } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
@Injectable({ providedIn: 'root' })
export class QueryParamsService {
constructor(private route: ActivatedRoute) {}
getParam(paramName: string): Observable<string> {
return this.route.queryParams.pipe(
map(params => params[paramName])
);
}
}
Затем используйте его в компоненте:
// products.component.ts
import { Component, OnInit } from '@angular/core';
import { QueryParamsService } from './query-params.service';
@Component({...})
export class ProductsComponent implements OnInit {
category: string;
constructor(private queryParamsService: QueryParamsService) {}
ngOnInit() {
this.queryParamsService.getParam('category').subscribe(value => {
this.category = value;
});
}
}
Когда это полезно:
- Когда один и тот же набор параметров нужен в разных компонентах
- Для централизованной обработки ошибок (например, если параметр отсутствует)
- Для удобного тестирования — сервис легко замокать
Этот подход делает код чище и переиспользуемым, особенно в больших проектах.