66

In my routable component I have

@RouteConfig {
  {path: '/login',   name: 'Login', component: LoginComponent}
}  

But how do I get the query params if I go to app_url/login?token=1234?

Amir
  • 8,821
  • 7
  • 44
  • 48
monty_lennie
  • 2,871
  • 2
  • 29
  • 49
  • Angular 2.1.0 provides an observable of the ActivatedRoute one should use now. Check my answer. – marcel Nov 21 '16 at 13:58

12 Answers12

52

RouteParams are now deprecated , So here is how to do it in the new router.

this.router.navigate(['/login'],{ queryParams: { token:'1234'}})

And then in the login component you can take the parameter,

constructor(private route: ActivatedRoute) {}
ngOnInit() {
    // Capture the token  if available
    this.sessionId = this.route.queryParams['token']

}

Here is the documentation

MrBoJangles
  • 12,127
  • 17
  • 61
  • 79
Jayantha Lal Sirisena
  • 21,216
  • 11
  • 71
  • 92
  • 10
    in order to get this to work I had to do this.route.snapshot.queryParams... – Lyle Rolleman May 17 '17 at 22:05
  • To add to this, it seems now (Currently, angular 5) that you need to reference snapshot, if youre reading this ensure you include .snapshot.queryParams to save time and read up on it here https://angular.io/guide/router#!#optional-route-parameters thanks @LyleRolleman for pointing this out – Cacoon Feb 27 '18 at 03:19
50

To complement the two previous answers, Angular2 supports both query parameters and path variables within routing. In @RouteConfig definition, if you define parameters within a path, Angular2 handles them as path variables and as query parameters if not.

Let's take a sample:

@RouteConfig([
  { path: '/:id', component: DetailsComponent, name: 'Details'}
])

If you call the navigate method of the router like this:

this.router.navigate( [
  'Details', { id: 'companyId', param1: 'value1'
}]);

You will have the following address: /companyId?param1=value1. The way to get parameters is the same for both, query parameters and path variables. The difference between them is that path variables can be seen as mandatory parameters and query parameters as optional ones.

Hope it helps you, Thierry

UPDATE: After changes in router alpha.31 http query params no longer work (Matrix params #2774). Instead angular router uses so called Matrix URL notation.

Reference https://angular.io/docs/ts/latest/guide/router.html#!#optional-route-parameters:

The optional route parameters are not separated by "?" and "&" as they would be in the URL query string. They are separated by semicolons ";" This is matrix URL notation — something you may not have seen before.

Martin Nuc
  • 5,604
  • 2
  • 42
  • 48
Thierry Templier
  • 198,364
  • 44
  • 396
  • 360
  • 12
    I was looking for this for hours! But it doesn't work like that, the URL should look like this `/companyId;param1=value1;param2=value2`. Anyway thanks for pointing me in the right way, you could update your answer if I am right. – Silencer Feb 09 '16 at 10:21
  • 1
    I agree with Silcener. The ? does not work, instead I have to use the semicolon as well. – abedurftig Apr 14 '16 at 21:01
  • The latest documentation for the router says: "The query string parameters are no longer separated by "?" and "&". They are separated by semicolons (;) This is matrix URL notation..." – reduckted May 22 '16 at 23:45
  • 2
    I hate to down vote but this excellent answer needs to be updated. – Methodician Jul 30 '16 at 00:21
  • 3
    why on earth they use matrix URL notation and how to switch back. This is creating problems sending parameters containing /, + and = signs – Toolkit Jun 03 '17 at 12:55
  • I realize that this answer was accepted in the past but since the "UPDATE" mentioned in the post there isn't a valid answer to query parameter navigation. Stephen's answer helped me out by breaking down the required Navigate parameters into variables. Specifically: let navigationExtras = { queryParams: { 'session_id': sessionId }, fragment: 'anchor' }; – samneric Jan 27 '18 at 00:37
  • How to get these matrix url notation (using `;`) parameters now? Just the same way as normal query parameters with `?` and `&`? Eg. `activeRoute.snapshot.params['param1'];` – Melroy van den Berg May 01 '18 at 21:10
  • Apparently if you use `activeRoute.snapshot.queryParams`, that doesn't work with the `;` notation (but works with the `?` and `&` notation). `activeRoute.snapshot.params` is what seems to work with the new `;` notation. It sort of makes sense, but not really intuitive. – Leaky Jul 19 '19 at 22:41
21

It seems that RouteParams no longer exists, and is replaced by ActivatedRoute. ActivatedRoute gives us access to the matrix URL notation Parameters. If we want to get Query string ? paramaters we need to use Router.RouterState. The traditional query string paramaters are persisted across routing, which may not be the desired result. Preserving the fragment is now optional in router 3.0.0-rc.1.

import { Router, ActivatedRoute } from '@angular/router';
@Component ({...})
export class paramaterDemo {
  private queryParamaterValue: string;
  private matrixParamaterValue: string;
  private querySub: any;
  private matrixSub: any;

  constructor(private router: Router, private route: ActivatedRoute) { }
  ngOnInit() {
    this.router.routerState.snapshot.queryParams["queryParamaterName"];
    this.querySub = this.router.routerState.queryParams.subscribe(queryParams => 
      this.queryParamaterValue = queryParams["queryParameterName"];
    );

    this.route.snapshot.params["matrixParameterName"];
    this.route.params.subscribe(matrixParams =>
      this.matrixParamterValue = matrixParams["matrixParameterName"];
    );
  }

  ngOnDestroy() {
    if (this.querySub) {
      this.querySub.unsubscribe();
    }
    if (this.matrixSub) {
      this.matrixSub.unsubscribe();
    }
  }
}

We should be able to manipulate the ? notation upon navigation, as well as the ; notation, but I only gotten the matrix notation to work yet. The plnker that is attached to the latest router documentation shows it should look like this.

let sessionId = 123456789;
let navigationExtras = {
  queryParams: { 'session_id': sessionId },
  fragment: 'anchor'
};

// Navigate to the login page with extras
this.router.navigate(['/login'], navigationExtras);
Ahmad Baktash Hayeri
  • 5,802
  • 4
  • 30
  • 43
Stephen
  • 1,603
  • 16
  • 19
  • 2
    Got the traditional query params working thanks to this answer. Matrix notation has issues in Hotmail. If you need to send the user an activation link (with params) Hotmail will encode the semicolon, breaking the URL. – Markus Pint Jul 22 '16 at 11:17
  • Hi Stephen what does it mean "The traditional query string paramaters are persisted across routing " can you please give us some examples ? I did'nt get it I have also read the docs but I'm still struggling with that. – AndroidLover Jul 25 '16 at 20:13
  • Say you navigate to your page via http:/someurl/a-route?do-thing=delete-variable, then navigate via this.router.navigate(['/login']) you will end up at http:/someurl/login?do-thing=set-variable. If you did http:/someurl/a-route;do-thing=set-variable then navigate you end up at http:/someurl/login – Stephen Jul 28 '16 at 16:31
  • 3.0.0-rc.1 (2016-08-09) "Query params and fragment are not longer preserved by default" https://github.com/angular/angular/blob/master/modules/@angular/router/CHANGELOG.md#breaking-changes – Stephen Aug 23 '16 at 16:31
  • Property 'router' does not exist on type 'YourComponent' – Toolkit Dec 05 '16 at 16:40
  • I'm confused. 'YourComponent' doesn't exist anywhere in this answer. – Stephen Dec 06 '16 at 23:10
17

This worked for me (as of Angular 2.1.0):

constructor(private route: ActivatedRoute) {}
ngOnInit() {
  // Capture the token  if available
  this.sessionId = this.route.snapshot.queryParams['token']

}
Amir
  • 8,821
  • 7
  • 44
  • 48
brando
  • 8,215
  • 8
  • 40
  • 59
6

(For Childs Route Only such as /hello-world)

In the case you would like to make this kind of call :

/hello-world?foo=bar&fruit=banana

Angular2 doesn't use ? nor & but ; instead. So the correct URL should be :

/hello-world;foo=bar;fruit=banana

And to get those data :

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

private foo: string;
private fruit: string;

constructor(
  private route: ActivatedRoute,
  private router: Router
  ) {}

ngOnInit() {
  this.route.params.forEach((params: Params) => {
      this.foo = params['foo'];
      this.fruit = params['fruit'];
  });
  console.log(this.foo, this.fruit); // you should get your parameters here
}

Source : https://angular.io/docs/ts/latest/guide/router.html

Wetteren Rémi
  • 598
  • 6
  • 11
  • 3
    Angular2 uses `;` (matrix parameter syntax) for query parameters of child routes and `?` for query parameters of the root route. – Günter Zöchbauer Sep 26 '16 at 09:25
  • I try to run it like this and get the following when I do npm start: aot/app/app.component.ngfactory.ts(45,30): error TS2346: Supplied parameters do not match any signature of call target. – jjj Oct 04 '16 at 12:06
5

Angular2 v2.1.0 (stable):

The ActivatedRoute provides an observable one can subscribe.

  constructor(
     private route: ActivatedRoute
  ) { }

  this.route.params.subscribe(params => {
     let value = params[key];
  });

This triggers everytime the route gets updated, as well: /home/files/123 -> /home/files/321

marcel
  • 3,231
  • 8
  • 43
  • 76
3

The simple way to do that in Angular 7+ is to:

Define a path in your ?-routing.module.ts

{ path: '/yourpage', component: component-name }

Import the ActivateRoute and Router module in your component and inject them in the constructor

contructor(private route: ActivateRoute, private router: Router){ ... }

Subscribe the ActivateRoute to the ngOnInit

ngOnInit() {

    this.route.queryParams.subscribe(params => {
      console.log(params);
      // {page: '2' }
    })
}

Provide it to a link:

<a [routerLink]="['/yourpage']" [queryParams]="{ page: 2 }">2</a>
Fortedx
  • 39
  • 3
2

Angular 4:

I have included JS (for OG's) and TS versions below.

.html

<a [routerLink]="['/search', { tag: 'fish' } ]">A link</a>

In the above I am using the link parameter array see sources below for more information.

routing.js

(function(app) {
    app.routing = ng.router.RouterModule.forRoot([
        { path: '', component: indexComponent },
        { path: 'search', component: searchComponent }
    ]);
})(window.app || (window.app = {}));

searchComponent.js

(function(app) {
    app.searchComponent =
        ng.core.Component({
            selector: 'search',
                templateUrl: 'view/search.html'
            })
            .Class({
                constructor: [ ng.router.Router, ng.router.ActivatedRoute, function(router, activatedRoute) {
                // Pull out the params with activatedRoute...
                console.log(' params', activatedRoute.snapshot.params);
                // Object {tag: "fish"}
            }]
        }
    });
})(window.app || (window.app = {}));

routing.ts (excerpt)

const appRoutes: Routes = [
  { path: '', component: IndexComponent },
  { path: 'search', component: SearchComponent }
];
@NgModule({
  imports: [
    RouterModule.forRoot(appRoutes)
    // other imports here
  ],
  ...
})
export class AppModule { }

searchComponent.ts

import 'rxjs/add/operator/switchMap';
import { OnInit } from '@angular/core';
import { Router, ActivatedRoute, Params } from '@angular/router';

export class SearchComponent implements OnInit {

constructor(
   private route: ActivatedRoute,
   private router: Router
) {}
ngOnInit() {
    this.route.params
      .switchMap((params: Params) => doSomething(params['tag']))
 }

More infos:

"Link Parameter Array" https://angular.io/docs/ts/latest/guide/router.html#!#link-parameters-array

"Activated Route - the one stop shop for route info" https://angular.io/docs/ts/latest/guide/router.html#!#activated-route

Community
  • 1
  • 1
Ally
  • 2,711
  • 1
  • 16
  • 17
2

For Angular 4

Url:

http://example.com/company/100

Router Path :

const routes: Routes = [
  { path: 'company/:companyId', component: CompanyDetailsComponent},

]

Component:

@Component({
  selector: 'company-details',
  templateUrl: './company.details.component.html',
  styleUrls: ['./company.component.css']
})
export class CompanyDetailsComponent{
   companyId: string;

   constructor(private router: Router, private route: ActivatedRoute) {
          this.route.params.subscribe(params => {
          this.companyId = params.companyId;
          console.log('companyId :'+this.companyId);
     }); 
  }
}

Console Output:

companyId : 100

Amir
  • 8,821
  • 7
  • 44
  • 48
1

According to Angular2 documentation you should use:

@RouteConfig([
   {path: '/login/:token', name: 'Login', component: LoginComponent},
])

@Component({ template: 'login: {{token}}' })
class LoginComponent{
   token: string;
   constructor(params: RouteParams) {
      this.token = params.get('token');
   }
}
suvroc
  • 3,058
  • 1
  • 15
  • 29
1

Angular 5+ Update

The route.snapshot provides the initial value of the route parameter map. You can access the parameters directly without subscribing or adding observable operators. It's much simpler to write and read:

Quote from the Angular Docs

To break it down for you, here is how to do it with the new router:

this.router.navigate(['/login'], { queryParams: { token:'1234'} });

And then in the login component (notice the new .snapshot added):

constructor(private route: ActivatedRoute) {}
ngOnInit() {
    this.sessionId = this.route.snapshot.queryParams['token']

}
Kyle Krzeski
  • 6,183
  • 6
  • 41
  • 52
1

In Angular 6, I found this simpler way:

navigate(["/yourpage", { "someParamName": "paramValue"}]);

Then in the constructor or in ngInit you can directly use:

let value = this.route.snapshot.params.someParamName;
Andrew
  • 7,602
  • 2
  • 34
  • 42