Angular URL State management with Query Params or Route Params
Tags: angular, javascript, webdev, typescript
Published: 2022-07-29 05:37:00

This blog post explains the process to maintain state using browser URL. In Angular there are couple of different ways to manage the state

1. Angular Services
2. State Management Library like NgRx, Akita, Elf etc.

But in some cases, you may want to share URL  and let others see the exact list of items (same order and filters applied). For example, when search for a flight in Travel website and find a good deal on certain dates, when you share the URL with your friend, for them it would load web page with default selection. But with URL state management, all changes are updated in URL and anyone using the URL would see the same selection.

------
## Query Params vs Route Params

This can be archived in one of the 2 ways
1. Query Parameters
2. Route Parameters

Query Parameters are a defined set of parameters attached to the end of a url and follow the standard syntax, starts with "?" then each extra parameter followed by "&" 

```
https://DOMAIN_NAME/employee/all?pageIndex=5&pageSize=10&sortDirection=asc&sortBy=salary
```
Route Parameters are similar Query Parameters except they only have single parameter separator like ";" and this can be changed
```
https://DOMAIN_NAME/employee/all;pageIndex=5;pageSize=10;sortDirection=asc;sortBy=salary

```
You can use either one in your project. I typically gravitate towards Query Parameters since they are most common

-----
## Overview
In this blog post we preserve angular materiel table sorting column, sorting order, page size, page index, search text etc.. selections in URL. When user goes to another page by clicking on URL and then later come back to the old page by clicking on browser back button, user will see same results. But this can also be applied to **inputs, tables, tab selection** etc.

As defined in this example, we have all-employees component that displays list of employees in Mat table. It supports following operations
1. Sorting
2. Filtering
3. Pagination

{% embed https://gist.github.com/pavankjadda/2407ad0f441df27e6da95aee1f929ce4 %}

## Update the URL:
The all employees component defines table data source, adds data, assigns paginator and sorter. See the complete component source code here. To store the user selections in the URL the `methodupdateRouteParameters()` listens for all events on table
{% embed https://gist.github.com/pavankjadda/1f5d6993bbd53a8aaa8820a33fe429a4 %}
When user changes sorting order of a column, enters a filter text or changes page size or page index, this method updates the URL. And it will look like below

```
https://DOMAIN_NAME/employee/all?pageIndex=5&pageSize=10&searchText=&sortDirection=asc&sortBy=salary
```

if you want to use Route Parameters, you can make a small change in above code at line 15.
```
const urlTree = this.router.createUrlTree(['/employee/all',params]);
```
then URL becomes
```
https://DOMAIN_NAME/employee/all;pageIndex=5;pageSize=10;searchText=;sortDirection=asc;sortBy=salary
```

## Load Webpage with Selected Options:
After changing sorting, filtering, pagination options and reload the web page or opening this URL in different browser tab, should load the table with exact selections.
{% embed https://gist.github.com/pavankjadda/161fca7fe179b1c0369bcb98357edf76 %}

The `mapTableData()` method assigns data to table data source and formats table if any of the table options present in the URL.

For example, when user access the link 
```
https://DOMAIN_NAME/employee/all?pageIndex=5&pageSize=10&searchText=&sortDirection=asc&sortBy=salary
```

the table should show 5th page with page size 10 sort by Salary column in Ascending order. To achieve this, we need to check for these parameters and modify the table data source.
-----
Code uploaded to [Stackblitz](https://stackblitz.com/edit/angular-ivy-ecw17i?file=src/app/app.component.ts) for reference. Happy Coding :)