Howard Paget
Projects
About

Angular: Get Query Parameters from an Route

Dec 30, 2021
angular

Angular provides access to the query parameters of the current route through the queryParams property of ActivatedRoute. queryParams is an observable so we can subscribe to it to receive it’s current value and any changes to it value.

The example below shows how a component can access the query parameters for a route such as:

  • The constructor requires an ActivatedRoute instance which Angular will inject.
  • In ngOnInit we subscribe to changes to this.route.queryParams and use the values for search for products.
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { ProductService } from '../search.service';

@Component({
  selector: 'app-search',
  templateUrl: './search.component.html',
  styleUrls: ['./search.component.css']
})
export class SearchComponent implements OnInit {

  constructor(private route: ActivatedRoute, private productService: ProductService) {}

  ngOnInit(): void {
    this.route.queryParams
      .subscribe(params => {
        console.log(params); // e.g. { "query": "shoes", "min_price": "10", "max_price": "75" }
        this.productService.search(params.query, params.min_price, params.max_price)
          .subscribe(products => {
            // do something with products...
          })
      });
  }

}

Test a component that uses query parameters

Angular allows us to provide a configured instance of ActivatedRoute with a set value for queryParams.

  • Configure the test to provide a set value of queryParams.
  • Construct a mock instance of ProductService.
  • Verify that out component used the values from queryParams to call productService.search(…).
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { ActivatedRoute } from '@angular/router';
import { of } from 'rxjs';
import { ProductService } from '../search.service';

import { SearchComponent } from './search.component';

describe('SearchComponent', () => {
  let component: SearchComponent;
  let fixture: ComponentFixture<SearchComponent>;
  let mockProductService: ProductService;

  beforeEach(waitForAsync(() => {
    TestBed.configureTestingModule({
      declarations: [SearchComponent],
      providers: [
        {
          provide: ActivatedRoute,
          useValue: {
            queryParams: of({ query: 'shoes', min_price: 10, max_price: 75 })
          }
        }
      ]
    });

    mockProductService = TestBed.inject(ProductService);
    spyOn(mockProductService, 'search').and.returnValue(of([]));
  }
  ));

  beforeEach(() => {
    fixture = TestBed.createComponent(SearchComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it('should have called product service with args from query params', () => {
    expect(component).toBeTruthy();
    expect(mockProductService.search).toHaveBeenCalledWith('shoes', 10, 75);
  });
});