4
votes

Related to but not a duplicate of: How to keep query string parameters in URL when accessing a route of an Angular 2 app?

I have a very basic Angular app, and when I add a query parameter, it's erased (from the browser's url and everywhere else it would seem) before the code hits the app.component constructor.

Note: it is on the initial load (and subsequent reloads) that query parameters appear to be stripped

Example: navigating to localhost:8081/calculator?a=1 is changed to localhost:8081/calculator

I've tried this in Angular 4.3.1, 4.4.6 and 5.0.4, with the same result.

Here's my route config:

const appRoutes: Routes = [
    {
        path: 'calculator',
        component: CalculatorComponent
    }
];

export const routing: ModuleWithProviders = RouterModule.forRoot(appRoutes);

Here's the main app component's constructor:

public constructor(private router: Router, private route: ActivatedRoute) {
    console.log('entered app constructor');
    this.route.queryParamMap.subscribe(params => {
        console.log('app', params);
    });
}

Here's the calculator component's constructor:

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

Here's the log I see in chrome:

chrome log

Why is my query parameter erased?

UPDATE I do have navigation configured in the app component like so:

let navigationExtras: NavigationExtras = {
    queryParamsHandling: 'preserve',
    preserveFragment: true
};
this.router.navigate(['/calculator'], navigationExtras);

Note that the query parameters are already gone before it gets here though...

4
Could this have anything to do with no query params being identified in the route?Kay
@KHAN you define parameters in the route, but not query parametersAnders
@Anders Yeah gotchaKay
@PankajParkar I may need to do that, but first I need to solve the issue of the query parameters disappearing entirely from the urlAnders
@Anders then i think you are looking for this.route.queryParams/queryParamMap?Kay

4 Answers

3
votes

The issue you are having is because you are calling this.router.navigate(['/calculator'], navigationExtras); inside your app component constructor or OnInit. Remember that queryParamMap is an observable, and so when you call navigate, the call will happen before your subscriber gets called. To fix your problem, just remove the navigate call. If you want your app component to autoredirect to calculator, the simplest safe method is to just change your paths to include:

routes: Routes = [ {path: '', redirectTo: 'calculator', pathMatch: 'full'}, ... ]

There is a plunker that should illustrate this. To get routing in plunker working I used HashLocation strategy though, so make sure you use /#/... when playing.

1
votes

if you want to retrieve query paramaters, then it is done using queryParam/queryParamMap..

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

You may need to preserve the query parameters, or merge them as stated here.

https://angular.io/api/router/NavigationExtras

v4

preserveQueryParams: true

v5

queryParamsHandling: 'preserve'
0
votes

You need to assign your query params to the queryParams Object.

Try:

this.router.navigate(['/calculator'], {queryParams: {a: 1}});

or add this to your navigation extras:

let navigationExtras: NavigationExtras = {
    queryParamsHandling: 'preserve',
    preserveFragment: true,
    queryParams: {a:1}
};
0
votes

This should work.

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

resetUrlQueryParams(){
  this.router.navigate([], 
      {
        relativeTo: this.activatedRoute,
        queryParams: {}
      });
}