38

For example I am on route /cars?type=coupe and I want to navigate to the same endpoint with additional query params (but keeping existing one). I am trying something like this

<a [routerLink]="['/cars']" [queryParams]="{model: 'renault'}" preserveQueryParams>Click</a>

The initial query params are preserved (type=cars) but added ones (model=renault) are ignored. Is this expected/correct behavior or is some kind of bug? Looks like preserveQueryParams has priority over queryParams? Is there any other smooth solution?

1
  • 1
    When using Anguar 4, I see preserveQueryParams is deprecated, use queryParamsHandling instead ??? Commented May 1, 2017 at 12:49

4 Answers 4

50

In Angular 4+, preserveQueryParams has been deprecated in favor of queryParamsHandling. The options are either 'merge' or 'preserve'.

In-code example (used in NavigationExtras):

this.router.navigate(['somewhere'], { queryParamsHandling: "preserve" });

In-template example:

<a [routerLink]="['somewhere']" queryParamsHandling="merge">
Sign up to request clarification or add additional context in comments.

2 Comments

Great answer! might want to use merge in your first example as it is the setting the OP wants
Thank you for your answer, This should be the accepted answer, I have no idea why people are answering with a complex answers on a totally wrong directions!, as a RoR developer, never seen such as this mess anywhere among the community, and I'm saying this because I've had a real hard times finding a simple answer for a simple question :S, Thanks again for your answer :)
14
+25

It just works this way unfortunately:

const q = preserveQueryParams ? this.currentUrlTree.queryParams : queryParams;

You could try to add custom directive like this:

@Directive({selector: 'a[routerLink][merge]'})
export class RouterLinkDirective implements OnInit
{

    @Input()
    queryParams: {[k: string]: any};

    @Input()
    preserveQueryParams: boolean;


    constructor(private link:RouterLinkWithHref, private route: ActivatedRoute )
    {
    }

    public ngOnInit():void
    {
        this.link.queryParams = Object.assign(Object.assign({}, this.route.snapshot.queryParams), this.link.queryParams);
        console.debug(this.link.queryParams);
    }
}


<a [routerLink]="['/cars']" merge [queryParams]="{model: 'renault'}">Click</a>

Update: See DarkNeuron answer below.

Comments

1

There is an open issue and also already a pull request to make preserveQueryParams a router setting instead of a per navigation setting

Comments

0

This can be handled using relativeTo and queryParamsHandling properties.

Try like this:

constructor(private _route: ActivatedRoute, private _router: Router)


this._router.navigate(
    [],
    {
      relativeTo: this._route,
      queryParams: { model: 'renault' },
      queryParamsHandling: 'merge'
 });

Comments