252
votes

I'm using angular 5.0.3, I would like to start my application with a bunch of query parameters like /app?param1=hallo&param2=123. Every tip given in How to get query params from url in Angular 2? does not work for me.

Any ideas how to get query parameters work?

private getQueryParameter(key: string): string {
  const parameters = new URLSearchParams(window.location.search);
  return parameters.get(key);
}

This private function helps me to get my parameters, but I don't think it is the right way in new Angular environment.

[update:] My main app looks like

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

  constructor(private route: ActivatedRoute) {}

  ngOnInit(): void {
    // would like to get query parameters here...
    // this.route...
  }
}
19
Are you using routers? Where is the URL coming from?Vinod Bhavnani
Yes, have a ActivatedRoute. I updated my question to show how my main component looks like.Lars
Can you also show me your route constant, where you have setup all the routes?Vinod Bhavnani
const appRoutes: Routes = [ {path: "one", component: PageOneComponent}, {path: "", redirectTo: "/one", pathMatch: "full"}, {path: "**", redirectTo: "/one"} ]; My Route constant. I would like to get all parameters in the main app store it in a DTO, then navigate to an other page. Page navigation works as expected, but I get the query parameters at main only by my 'getQueryParameter' function. I realize in your question that there exist something I have forgotten. Do I need to mark my parameter names anywhere?Lars
Yes, in your routes, you need to define the parameters as well. If you check the routing docs on angular.io, you can see how they define parameters on a particular route. Something like this {path: 'abc/:param1', component: componentClassName}Vinod Bhavnani

19 Answers

315
votes

In Angular 5, the query params are accessed by subscribing to this.route.queryParams (note that later Angular versions recommend queryParamMap, see also other answers).

Example: /app?param1=hallo&param2=123

param1: string;
param2: string;
constructor(private route: ActivatedRoute) {
    console.log('Called Constructor');
    this.route.queryParams.subscribe(params => {
        this.param1 = params['param1'];
        this.param2 = params['param2'];
    });
}

whereas, the path variables are accessed by this.route.snapshot.params

Example: /param1/:param1/param2/:param2

param1: string;
param2: string;
constructor(private route: ActivatedRoute) {
    this.param1 = this.route.snapshot.params.param1;
    this.param2 = this.route.snapshot.params.param2;
}
165
votes

This is the cleanest solution for me

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

export class MyComponent {
  constructor(
    private route: ActivatedRoute
  ) {}

  ngOnInit() {
    const firstParam: string = this.route.snapshot.queryParamMap.get('firstParamKey');
    const secondParam: string = this.route.snapshot.queryParamMap.get('secondParamKey');
  }
}
113
votes

I know that OP asked for Angular 5 solution, but yet for all of you who stumbles upon this question for newer (6+) Angular versions. Citing the Docs, regarding ActivatedRoute.queryParams (which most of other answers are based on):

Two older properties are still available. They are less capable than their replacements, discouraged, and may be deprecated in a future Angular version.

params — An Observable that contains the required and optional parameters specific to the route. Use paramMap instead.

queryParams — An Observable that contains the query parameters available to all routes. Use queryParamMap instead.

According to the Docs, the simple way to get the query params would look like this:

constructor(private route: ActivatedRoute) { }

ngOnInit() {
    this.param1 = this.route.snapshot.paramMap.get('param1');
    this.param2 = this.route.snapshot.paramMap.get('param2');
}

For more advanced ways (e.g. advanced component re-usage) see this Docs chapter.

EDIT:

As it correctly stated in comments below, this answer is wrong - at least for the case specified by OP.

OP asks to get global query parameters (/app?param1=hallo&param2=123); in this case you should use queryParamMap (just like in @dapperdan1985 answer).

paramMap, on the other hand, is used on parameters specific to the route (e.g. /app/:param1/:param2, resulting in /app/hallo/123).

Thanks to @JasonRoyle and @daka for pointing it out.

30
votes

You can also Use HttpParams, such as:

  getParamValueQueryString( paramName ) {
    const url = window.location.href;
    let paramValue;
    if (url.includes('?')) {
      const httpParams = new HttpParams({ fromString: url.split('?')[1] });
      paramValue = httpParams.get(paramName);
    }
    return paramValue;
  }
19
votes

Query and Path Params (Angular 8)

For url like https://myapp.com/user/666/read?age=23 use

import { combineLatest } from 'rxjs';
// ...

combineLatest( [this.route.paramMap, this.route.queryParamMap] )
  .subscribe( ([pathParams, queryParams]) => {
    let userId = pathParams.get('userId');    // =666
    let age    = queryParams.get('age');      // =23
    // ...
  })

UPDATE

In case when you use this.router.navigate([someUrl]); and your query parameters are embedded in someUrl string then angular encodes a URL and you get something like this https://myapp.com/user/666/read%3Fage%323 - and above solution will give wrong result (queryParams will be empty, and path params can be glued to last path param if it is on the path end). In this case change the way of navigation to this

this.router.navigateByUrl(someUrl);
16
votes
import { ParamMap, Router, ActivatedRoute } from '@angular/router';

constructor(private route: ActivatedRoute) {}

ngOnInit() {
    console.log(this.route.snapshot.queryParamMap);
}

UPDATE

import { Router, RouterStateSnapshot } from '@angular/router';

export class LoginComponent {
    constructor(private router: Router) {
        const snapshot: RouterStateSnapshot = router.routerState.snapshot;
        console.log(snapshot);  // <-- hope it helps
    }
}
10
votes

its work for me:

constructor(private route: ActivatedRoute) {}

ngOnInit()
{
    this.route.queryParams.subscribe(map => map);
    this.route.snapshot.queryParams; 
}

look more options How get query params from url in angular2?

8
votes

Unfortunately, the cleanest solution is not the most extensible solution. In recent versions of Angular, it is suggested in the other answers that you can easily get the query params using the ActivatedRoute Injectible and specifically utilizing either the snapshot property:

this.route.snapshot.queryParamMap.get('param')

or the subscribe property (used in cases where the query string will update, e.g. navigating through user ids):

this.route.queryParamMap.subscribe(params => console.log(params));

I am here to tell you that these solutions have a gaping flaw that has not been resolved for some time: https://github.com/angular/angular/issues/12157

All in all, the only bullet proof solution is to use good old vanilla javascript. In this case, I created a service for URL manipulation:

import { Injectable } from '@angular/core';
import { IUrl } from './iurl';

@Injectable()
export class UrlService {
    static parseQuery(url: string): IUrl {
        const query = url.slice(url.indexOf('?')+1).split('&').reduce( (acc,query) => {
            const parts = query.split('=');
            acc[parts[0]] = parts[1];
            return acc;
        }, {});

        return {
            a: query['a'],
            b: query['b'],
            c: query['c'],
            d: query['d'],
            e: query['e']
        }
    }
}
7
votes

Angular Router provides method parseUrl(url: string) that parses url into UrlTree. One of the properties of UrlTree are queryParams. So you can do sth like:

this.router.parseUrl(this.router.url).queryParams[key] || '';
5
votes

Stumbled across this question when I was looking for a similar solution but I didn't need anything like full application level routing or more imported modules.

The following code works great for my use and requires no additional modules or imports.

  GetParam(name){
    const results = new RegExp('[\\?&]' + name + '=([^&#]*)').exec(window.location.href);
    if(!results){
      return 0;
    }
    return results[1] || 0;
  }

  PrintParams() {
    console.log('param1 = ' + this.GetParam('param1'));
    console.log('param2 = ' + this.GetParam('param2'));
  }

http://localhost:4200/?param1=hello&param2=123 outputs:

param1 = hello
param2 = 123
2
votes

Simple Solution

 // in routing file
       {
            path: 'checkout/:cartId/:addressId',
            loadChildren: () => import('./pages/checkout/checkout.module').then(m => m.CheckoutPageModule)
          },

    // in Component file

            import { Router, ActivatedRoute } from '@angular/router';

                 constructor(
                      private _Router: ActivatedRoute
                  ) { }

                  ngOnInit() {
                    this.cartId = this._Router.snapshot.params.cartId;
                    this.addressId = this._Router.snapshot.params.addressId;
                    console.log(this.addressId, "addressId")
                    console.log(this.cartId, "cartId")
                  }
1
votes

When you have an empty route object, it's mainly due to the fact that you are not using a router-outlet in your app.component.html.

Without this, you won't be able to get a meaningful route object with non empty subObjects, particularly params & queryParams.

Try to add <router-outlet><router-outlet>just before calling your <app-main-component></app-main-component>

Before that, make sure you have your query param ready in app-routing > which export the class Route used by App component :

param: '/param/:dynamicParam', path: MyMainComponent

Last thing of course, to get your param, I personnaly use this.route.snapshot.params.dynamicParam where dynamicParam is the name used in your app-routing component :)

1
votes

Be careful with your routes. A "redirectTo" will remove|drop any query parameter.

const appRoutes: Routes [
 {path: "one", component: PageOneComponent},
 {path: "two", component: PageTwoComponent},
 {path: "", redirectTo: "/one", pathMatch: full},
 {path: "**", redirectTo: "/two"}
]

I called my main component with query parameters like "/main?param1=a&param2=b and assume that my query parameters arrive in the "ngOnInit()" method in the main component before the redirect forwarding takes effect.

But this is wrong. The redirect will came before, drop the query parameters away and call the ngOnInit() method in the main component without query parameters.

I changed the third line of my routes to

{path: "", component: PageOneComponent},

and now my query parameters are accessible in the main components ngOnInit and also in the PageOneComponent.

1
votes

Found in: Parent components gets empty Params from ActivatedRoute

Worked for me:

import {Component, OnDestroy, OnInit} from '@angular/core';
import { Router, ActivatedRoute, Params, RoutesRecognized } from '@angular/router';

@Component({
  selector: 'app-navigation-bar',
  templateUrl: './navigation-bar.component.html',
  styleUrls: ['./navigation-bar.component.scss']
})
export class NavigationBarComponent implements OnInit, OnDestroy {
  private sub: any;
  constructor(private route: ActivatedRoute, private router: Router) {}

  ngOnInit() {
    this.sub = this.router.events.subscribe(val => {
      if (val instanceof RoutesRecognized) {
        console.log(val.state.root.firstChild.params);
      }
    });
  }

  ngOnDestroy() {
    this.sub.unsubscribe();
  }

}
0
votes

Just stumbled upon the same problem and most answers here seem to only solve it for Angular internal routing, and then some of them for route parameters which is not the same as request parameters.

I am guessing that I have a similar use case to the original question by Lars.

For me the use case is e.g. referral tracking:

Angular running on mycoolpage.com, with hash routing, so mycoolpage.com redirects to mycoolpage.com/#/. For referral, however, a link such as mycoolpage.com?referrer=foo should also be usable. Unfortunately, Angular immediately strips the request parameters, going directly to mycoolpage.com/#/.

Any kind of 'trick' with using an empty component + AuthGuard and getting queryParams or queryParamMap did, unfortunately, not work for me. They were always empty.

My hacky solution ended up being to handle this in a small script in index.html which gets the full URL, with request parameters. I then get the request param value via string manipulation and set it on window object. A separate service then handles getting the id from the window object.

index.html script

const paramIndex = window.location.href.indexOf('referrer=');
if (!window.myRef && paramIndex > 0) {
  let param = window.location.href.substring(paramIndex);
  param = param.split('&')[0];
  param = param.substr(param.indexOf('=')+1);
  window.myRef = param;
}

Service

declare var window: any;

@Injectable()
export class ReferrerService {

  getReferrerId() {
    if (window.myRef) {
      return window.myRef;
    }
    return null;
  }
}
0
votes

The below code works for me

constructor(private route: ActivatedRoute) {   }
ngOnInit(): void {
   this.route.queryParams.subscribe(params => {
      console.log(params);
    });
}
-1
votes
/*
Example below url with two param (type and name) 
URL : http://localhost:4200/updatePolicy?type=Medicare%20Insurance&name=FutrueInsurance
*/ 
  constructor(private route: ActivatedRoute) {
    //Read url query parameter `enter code here`
  this.route.queryParams.subscribe(params => {
    this.name= params['type'];
    this.type= params['name'];
    alert(this.type);
    alert(this.name);

 });

  }
-3
votes

At, i think Angular 8:

ActivatedRoute.params has been replaced by ActivatedRoute.paramMap ActivatedRoute.queryParams has been replaced by ActivatedRoute.queryParamMap

-10
votes

If you're not using Angular router try, querystring. Install it

npm install --save querystring

to your project. In your component do something like this

import * as qs from 'querystring';
...
ngOnInit() {
   const params = qs.parse(window.location.search.substring(1));
   ...
}

The substring(1) is necessary because if you have something like this '/mypage?foo=bar' then the key name for will be ?foo