Antop
Antop

Reputation: 123

Angular 2, How to pass an array to the Router using queryParams

Is there some way to get this kind of URL in Angular 2?

http://example.com/the-route?param[]=value1&param[]=value2&param[]=value3

I'm trying to do it like it should be, using queryParams with the Router, but as queryParams accepts an Object I can't do this:

this.router.navigate(['/the-route'], queryParams: { 'param[]': 'value1', 'param[]': 'value2', 'param[]': 'value3' });

Because, of course, I can't use the same name (param[]) several times in the Object

I'm struggling with how to do this, but can't find a way

I've seen this post: Angular 2 pass array to router queryString. But there are no correct answers

Upvotes: 5

Views: 16853

Answers (5)

Ari Waisberg
Ari Waisberg

Reputation: 1304

Yo can do like this:

let object1 = {
  'name':'Charles',
  'age':21,
}

let params = {
  'student':JSON.stringify(object1),
  'carreer':'law',
}

this.router.navigate(['/the-route'], {queryParams: params});

and when you receive the 'student' param you just PARSE IT like this:

let student = JSON.parse (params['student']);

and that's it!

Upvotes: 4

Mohammad Kermani
Mohammad Kermani

Reputation: 5396

Not a lot related to the question, but might help people who come to this question from Google and are looking about how to pass an array to routerLink; so this answer might help them.

consider this example:

<a [routerLink]="['news', newsId, newsTitle]">

the first item (news) is a text because it's inside quotation marks, and other two items are variables that might be inside a ngFor

Upvotes: -1

Alexander Pisarev
Alexander Pisarev

Reputation: 46

There is no possibility to do this right now.

If You trace the router code yourself begining from router#navigate(), You can see that create_url_tree#tree() function builds a tree with stringified queryParams:

function tree(oldSegmentGroup, newSegmentGroup, urlTree, queryParams, fragment) {
  if (urlTree.root === oldSegmentGroup) {
    return new UrlTree(newSegmentGroup, stringify(queryParams), fragment);
  }
  return new UrlTree(replaceSegment(urlTree.root, oldSegmentGroup, newSegmentGroup), stringify(queryParams), fragment);
}

And stringify() does all the dirty work:

function stringify(params) {
  var /** @type {?} */ res = {};
  forEach(params, function (v, k) { return res[k] = "" + v; });
  return res;
}

Result of concatenation of string and array is a comma-delimited string.

There are a couple of issues about multiple query parameters with the same name, that was fixed in https://github.com/angular/angular/pull/11373. As You can see, modified url_tree#serializeQueryParams() does exactly what You need. But the problem is that serialization takes place a lot later as the tree will be built.

It seems that this is a bug in create_url_tree#tree() - it shouldn't stringify query params, because it is the area of responsibility of url_tree#serializeQueryParams(). I've removed call to stringify() locally and everything started working as it should.

As workaround You can stringify each query parameter manually with JSON.stringify(queryParamArray) before sending it to router#naviagate() and parse it with JSON.parse(param) in route.queryParams.subscribe(). URL looks horrible, but now it's the only way to pass arrays.

UPDATE: I created the issue in the angular repository: https://github.com/angular/angular/issues/14796

Upvotes: 2

Shailesh  kala
Shailesh kala

Reputation: 1852

you can use the navigation extras hope this might help you:

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

function(){
 let extra: any = [];


  let navigationExtras: NavigationExtras = {
      queryParams:extra
    };

 this.router.navigate(['/Questions'], navigationExtras);
}

Upvotes: 0

Rakesh Samal
Rakesh Samal

Reputation: 11

You can pass them as items in the router commands array:

[routerLink]="['/Questions', {queryParams: {id:1234, pageid:0}} ]"

See also https://angular.io/docs/ts/latest/guide/router.html#!#query-parameters

Upvotes: 1

Related Questions