Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to update matrix parameters in Angular2

In Angular2, is there a way to update a matrix parameter, but navigate to the same component? Basically would like to transition easily from a url that looks like:

/search;term=paris;pageSize=24;currentPage=1;someFilter=value;

to the same thing, but with currentPage updated upon pagination:

/search;term=paris;pageSize=24;currentPage=2;someFilter=value;

using router.navigate hasn't appeared to be the best option, since I'd have to write plenty of my own logic to re-construct the url for navigate's use (re-constructing something that already exists).

For kicks and giggles, I did try

this._router.navigate([this._router.url, {currentPage: this.pagination.currentPage}]);

but (as you might expect), the router is dumb to the fact that there are matrix parameters on the current url, so the result is not pretty.

EDIT: Should also mention that there may be any number of additional key/value pairs of matrix parameters, so hard-coding any route is out of the question

EDIT: I've since tried to use preserveQueryParams: true like:

this._router.navigate(["..", {currentPage: this.pagination.currentPage}], {preserveQueryParams: true});

in order to get to an easily usable/transferable solution, but that did not keep the matrix params on the route.

UPDATE: I've since implemented my own logic to get the required behavior, so here's a code snippet for the solution:

  let currentParamsArr: Params = this.route.snapshot.params;
  let currentParamsObj: any = { };
  for (let param in currentParamsArr) {
    currentParamsObj[param] = currentParamsArr[param];
  }
  currentParamsObj.currentPage = +pageNum; //typecasting shortcut

  this._router.navigate([currentParamsObj], { relativeTo: this.route });

This code loops through the parameters (as they stand in the snapshot), and creates an object out of them, then adds/edits the parameter that I desire to update, then navigates to the "new" route

But, this is not pretty, as I'll essentially have this same logic in many places of the program or have to make a modification to Router or provide some other generic method.

like image 248
Corbfon Avatar asked Dec 18 '16 06:12

Corbfon


People also ask

How to get the value of the parameter in angular component?

The Angular adds the map all the route parameters in the ParamMap object, which can be accessed from the ActivatedRoute service. The ParamMap makes it easier to work with parameters. We can use get or getAll methods to retrieve the value of the parameters in the component. Use the has method to check if a certain parameter exists.

How to preserve or merge query parameters in angular?

Using queryParamsHanding property we can preserve or merge query parameters in Angular. In Angular, query parameters are lost when we navigate from one route to another route. In the above example if we are navigating from http://localhost:4200/books?orderby=price to other route http://localhost:4200/e-books orderby parameter will be lost.

What is the difference between query parameters and angular route parameters?

Difference between query parameters and Angular route parameters. There are two main differences between Query parameters and angular route parameters. Angular route parameters are available only on one route, where as we can pass query parameters to any route. Query parameters are optional.

What is the parammap in angular?

The Angular adds the map all the route parameters in the ParamMap object, which can be accessed from the ActivatedRoute service The ParamMap makes it easier to work with parameters.


1 Answers

The approach that ended up working well for me is this:

let route: ActivatedRoute;
const newUrl = router.createUrlTree([
  merge({'a': 123}, route.snapshot.params)
], {relativeTo: route});

By using merge, you can add, update and subtract url parameters and then use router.navigateByUrl(newUrl) in order to execute.

add: merge({newParam: 111}, route.snapshot.params)

update: merge({param: 111}, route.snapshot.params)

subtract: merge({param: null}, route.snapshot.params)

Hope others find this as useful as I have.

Another example using Object.assign instead of merge:

let route = this.route; // The imported ActivatedRoute
let currentParamsObj: Params = Object.assign({}, route.snapshot.params);

let newParam = {};
newParam[key] = value;

let newUrl = this._router.createUrlTree([
        Object.assign(currentParamsObj, newParam)
    ], {relativeTo: this.route });

this._router.navigateByUrl(newUrl);
like image 131
Corbfon Avatar answered Oct 18 '22 06:10

Corbfon