Learn Angular The Right Way Angular Icon

Angular is complex, unless you have all the answers...

Getting Query Params from Angular's Router

In this post you’re going to learn how get query params from the URL in Angular by using the router snapshot, and also how to subscribe to route param changes.

To do this, we’ll be using the ActivatedRoute object and look at the best way to get the query params, depending on your scenario.

There are likely two things you want when reading query params. The first, a single time reading of the params. The second, you may wish to subscribe to the params to get notified when they change!

🕵️‍♂️ In previous versions of Angular, we could use various approaches such as this.route.params or this.route.queryParams, however as of recent Angular versions their use is discouraged as they will likely be deprecated in favour of this.route.queryParamsMap (which you’ll learn in this post!).

Angular Directives In-Depth eBook Cover

Free eBook

Directives, simple right? Wrong! On the outside they look simple, but even skilled Angular devs haven’t grasped every concept in this eBook.

  • Green Tick Icon Observables and Async Pipe
  • Green Tick Icon Identity Checking and Performance
  • Green Tick Icon Web Components <ng-template> syntax
  • Green Tick Icon <ng-container> and Observable Composition
  • Green Tick Icon Advanced Rendering Patterns
  • Green Tick Icon Setters and Getters for Styles and Class Bindings

Accessing the Query Params snapshot

Let’s take these example params:

/?filter=Pepperoni

To quickly get a synchronous reading of the query params we can inject the ActivatedRoute inside a component:

import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';

@Component({...})
export class FilterComponent implements OnInit {

  constructor(
    private route: ActivatedRoute
  ) {}

  ngOnInit() {
    const filter = this.route.snapshot.queryParamMap.get('filter');
    console.log(filter); // Pepperoni
  }
}

This is a nice and simple way to access your query params with Angular’s router, however it doesn’t give us any reactive benefits. This means we cannot subscribe to the query params, meaning if they were to change then we couldn’t get notified of the new value!

That’s where subscribing to the query params comes into play! So now depending on your scenario you can make the right choice for you.

Subscribing to Query Params

It’s time to get reactive! Instead of using the snapshot on the activated route, we’ll instead be using the this.route.queryParamMap Observable.

We can then .pipe() off the Observable and use the map operator to return a params.get() method call, passing in the name of the param we’d like to get:

import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, ParamMap } from '@angular/router';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';

@Component({...})
export class FilterComponent implements OnInit {
  filter$: Observable<string>;

  constructor(
    private route: ActivatedRoute
  ) {}

  ngOnInit() {
    this.filter$ = this.route.queryParamMap.pipe(
      map((params: ParamMap) => params.get('filter')),
    );
  }
}

We’d then bind this.filter$ to the Async Pipe via NgIf Async or NgFor Async. Alternatively, we can .subscribe() directly inside the component class:

import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, ParamMap } from '@angular/router';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';

@Component({...})
export class FilterComponent implements OnInit {
  filter$: Observable<string>;

  constructor(
    private route: ActivatedRoute
  ) {}

  ngOnInit() {
    this.filter$ = this.route.queryParamMap.pipe(
      map((params: ParamMap) => params.get('filter')),
    );

    // subscribe and log the params when they change
    // you could set to an internal variable or
    // bind the filter$ directly to the async pipe
    // ultimatecourses.com/blog/angular-ngfor-async-pipe
    this.filter$.subscribe(param => console.log(param));
  }
}

And that’s it! The benefit to this approach is we could then use something like combineLatest() with some data, and go and grab the item we are looking for from the data based on the query param.

This is enough to get you started though!

Managing subscriptions

Should you unsubscribe from the queryParamMap Observable? Nope! There’s no need. Angular’s router will manage the subscriptions for you, so this makes it a little bit easier and cleaner for us on the component class.

If you are serious about your Angular skills, your next step is to take a look at my Angular courses where you’ll learn Angular, TypeScript, RxJS and state management principles from beginning to expert level.

This makes it nice when dealing with your data in components as we can .pipe() directly off our queryParamMap and have the subscriptions handled for us!

Related blogs 🚀

Free eBooks:

Angular Directives In-Depth eBook Cover

JavaScript Array Methods eBook Cover

NestJS Build a RESTful CRUD API eBook Cover