14
votes

After searching multiple threads/questions on the various types of routing within Angular 4, I cannot resolve an issue linked to passing queryParams to an Angular 4 route.

When passing either into the url

http://localhost/search;x=y

through the template [queryParams]={x: 'y'}

<a [routerLink]="/search" [queryParams]="{x: 'y'}">Navigate</a>

or in the component class

this._router.navigate(['/search'], { queryParams: {x: 'y'} });

the result is the router throwing a match error:

Error: Cannot match any routes. URL Segment: 'search%3Fparam1%3Dtest1%26param2%3Dtest2'

When setting enableTracing to true, I can see the navigation encodes the suspect characters, which most likely is the reason it's failing to match.

I have a requirement to handle urls that contain queryParams and parse them for api calls, so the query param route must be used over required or optional params.

Has anyone had a similar issue and if so, is the encoding the root (ahem.) cause of the issue?

4
Could you show us the path of your route in the definition ? It should be { path: 'search/:x', component: MyComponent}. If not, here is your error !user4676340
Not quite. QueryParams should not be defined in the route definition. If they are ... then that is the problem. :-)DeborahK

4 Answers

23
votes

Query parameters result in a url that looks like this:

http://localhost/search?x=y

With a question mark, not a semicolon.

Here is a summary for how to work with query parameters.

enter image description here

Note that they are not configured as part of the route definition.

Your routerLink and navigate method looks correct.

Update :
make sure to use this import.

import { ActivatedRoute } from '@angular/router';
constructor(private route: ActivatedRoute) {}
12
votes

After some deliberation I was able to fix the issue.

I was using ActivatedRouteSnapshot to store the url (including query params) as a whole, then passing that through to the router.

I should have stored the query params in a separate object to the route and passed them in using

this._router.navigate(['/search'], { queryParams: paramsObj });

Of course the route matching failed as it couldn't match a route with all the query params added onto the end of the string.

3
votes

For example, you want to add a link that will redirect to the search page with variable: searchString = 'search'

<a [routerLink]="['/search', searchString]">Navigate</a>

In your component, you can create a navigation by using this._router.navigate(['/search', this.searchString]);, where searchString is declared as a const in both cases.

2
votes

Following code saved me:

         this.router.navigate(['route-name'], { queryParams: {key:'value'} });        

On the receiving end fetch the value by: ( I assume ActivatedRoute is injected place),

         this.route.queryParams.subscribe(params => {console.log(queryParams['key'])}

Or at template level you can write like this.

 **<a [routerLink]="['/login']" [queryParams]="{ key: 'employer'}" >sign in</a></p>**

Note: route is an instance of ActivatedRoute.