Difference Between QueryParamsHandling preserve and merge in Angular

Query parameters in Angular are optional parameters that are used to pass additional information to a route. These parameters are different from regular route parameters.

For example, let’s say you are on the /products page of your Angular application, you select some products and want to navigate to the /cart page but with the id of the product you have selected from the /products page.

This is how you can do it with the help of the Angular router:

import { Router } from '@angular/router';

constructor(private router: Router) { }

selectedProducts() {
  this.router.navigate(
    ['/cart'],
    {
      queryParams: { productId: '5' },   // Product Id
    }
  )
}

And this will result in the following URL:

http://localhost:4200/cart?productId=5

But the problem with these query parameters is that they are lost when you navigate to any subsequent route. This is the default behavior.

To overcome this problem, we need to set the value of the queryParamsHandling property inside the navigate() function. Which we are going to discuss next.


Understanding the difference between queryParamsHandling preserve and merge

Before diving deep into the difference between preserve and merge, let’s have a look at what are all possible values of queryParamsHandling:

  • "": It replaces the current query parameters with the new query parameters. If there are no new query parameters, the current query parameters are lost on any subsequent navigation. This is default.
  • "merge": The current query parameters are merged with the new query parameters. No query parameter is lost on any subsequent router navigation.
  • "preserve": Only the current query parameters are preserved. If you try to add new parameters, they will not be appended to the URL.

Okay, So now we have some sort of understanding of what exactly the queryParamsHandling does. But, to understand it deeply, we have to look at a few real-time examples.

Let’s say we have three routes /products, /cart, and /order in our Angular application.

We are currently on /products route, we select a product and want to send the selected product Id to the /cart route whenever we navigate to it.

Let’s not care about the queryParamsHandling for now. We will just go with the default value:

selectedProducts() {
  this.router.navigate(
    ['/cart'],
    {
      queryParams: { productId: '5' },   // Product Id
    }
  )
}

This will result in the following URL when we visit the /cart route:

http://localhost:4200/cart?productId=5

Now, let’s say we want to increment the quantity of the selected product in our cart. Say we incremented it to 2 and want to send it to the /order route whenever we visit it.

Here comes the role of queryParamsHandling. For example, If you keep it default i.e. queryParamsHandling: "", you will lose the product Id on navigating to the /order route.

addToCart() {
  this.router.navigate(
    ['/order'],
    {
      queryParams: { qty: 2 },   // Product quantity
      queryParamsHandling: ""
    }
  )
}

The /order route will only have one parameter qty, while the previous parameter productId will be lost:

http://localhost:4200/order?qty=2

On the other hand, if you set the queryParamsHandling to "merge", the productId and qty both parameters will be merged. No parameters will be lost:

addToCart() {
  this.router.navigate(
    ['/order'],
    {
      queryParams: { qty: 2 },   // Product quantity
      queryParamsHandling: "merge"
    }
  )
}

This will result in the following URL:

http://localhost:4200/order?productId=5&qty=2

Now, let’s understand the third value "preserve". It is a kind of intermediate of the above two values.

For example, if you set the queryParamsHandling to "preserve", only the current route parameters will be preserved. If you add any new parameters, they will be lost.

In our case, the current parameter is productId and the new parameter is qty. Therefore, only the current parameter i.e. productId will be preserved while the new parameter i.e. qty will be lost on navigating to the /order route.

addToCart() {
  this.router.navigate(
    ['/order'],
    {
      queryParams: { qty: 2 },   // Product quantity
      queryParamsHandling: "preserve"
    }
  )
}

This will result in the following URL:

http://localhost:4200/order?productId=5

Conclusion

So, if we put all the above points together, we can say that the difference between queryParamsHandling merge and preserve is that queryParamsHandling: "merge" merges the current query parameters with the new query parameters on subsequent navigations and no parameter is lost.

On the other hand, queryParamsHandling: "preserve" only preserves the current query parameters and the new query parameters are lost on subsequent navigations.

Thanks for reading.


Author

  • Manoj Kumar

    Hi, My name is Manoj Kumar. I am a full-stack developer with a passion for creating robust and efficient web applications. I have hands-on experience with a diverse set of technologies, including but not limited to HTML, CSS, JavaScript, TypeScript, Angular, Node.js, Express, React, and MongoDB.

    View all posts