Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Change route params without reloading in Angular 2

People also ask

How do I change the URL in an Angular application without reloading the route?

Redirect. When this button is clicked, we'll perform the URL change without loading the new route. import { Location } from '@angular/common'; 1import { Location } from '@angular/common';

What does ActivatedRoute do in Angular?

ActivatedRoutelink. Provides access to information about a route associated with a component that is loaded in an outlet. Use to traverse the RouterState tree and extract information from nodes.

What is skipLocationChange?

skipLocationChange: boolean. You can change the route, without changing the URL in the browser. This Navigates to a new URL without pushing a new state into history.

Where do you set the route parameter value in Angular?

The first way is through the route snapshot. The route snapshot provides the initial value of the route parameter map (called the paramMap ). You can access the parameters directly without subscribing or adding observable operators. The paramMap provides methods to handle parameter access like get , getAll , and has .


As of RC6 you can do the following to change URL without change state and thereby keeping your route history

    import {OnInit} from '@angular/core';

    import {Location} from '@angular/common'; 
    // If you dont import this angular will import the wrong "Location"

    @Component({
        selector: 'example-component',
        templateUrl: 'xxx.html'
    })
    export class ExampleComponent implements OnInit {
        
        constructor( private location: Location )
        {}

        ngOnInit() {    
            this.location.replaceState("/some/newstate/");
        }
    }

You could use location.go(url) which will basically change your url, without change in route of application.

NOTE this could cause other effect like redirect to child route from the current route.

Related question which describes location.go will not intimate to Router to happen changes.


Using location.go(url) is the way to go, but instead of hardcoding the url , consider generating it using router.createUrlTree().

Given that you want to do the following router call: this.router.navigate([{param: 1}], {relativeTo: this.activatedRoute}) but without reloading the component, it can be rewritten as:

const url = this.router.createUrlTree([], {relativeTo: this.activatedRoute, queryParams: {param: 1}}).toString()

 this.location.go(url);

For anyone like me finding this question the following might be useful.

I had a similar problem and initially tried using location.go and location.replaceState as suggested in other answers here. However I ran into problems when I had to navigate to another page on the app because the navigation was relative to the current route and the current route wasn't being updated by location.go or location.replaceState (the router doesn't know anything about what these do to the URL)

In essence I needed a solution that DIDN'T reload the page/component when the route parameter changed but DID update the route state internally.

I ended up using query parameters. You can find more about it here: https://angular-2-training-book.rangle.io/handout/routing/query_params.html

So if you need to do something like save an order and get an order ID you can update your page URL like shown below. Updating a centre location and related data on a map would be similar

// let's say we're saving an order. Initally the URL is just blah/orders
save(orderId) {
    // [Here we would call back-end to save the order in the database]

    this.router.navigate(['orders'], { queryParams: { id: orderId } });
    // now the URL is blah/orders?id:1234. We don't reload the orders
    // page or component so get desired behaviour of not seeing any 
    // flickers or resetting the page.
}

and you keep track of it within the ngOnInit method like:

ngOnInit() {
    this.orderId = this.route
        .queryParamMap
        .map(params => params.get('id') || null);
    // orderID is up-to-date with what is saved in database now, or if
    // nothing is saved and hence no id query paramter the orderId variable
    // is simply null.
    // [You can load the order here from its ID if this suits your design]
}

If you need to go direct to the order page with a new (unsaved) order you can do:

this.router.navigate(['orders']);

Or if you need to go direct to the order page for an existing (saved) order you can do:

this.router.navigate(['orders'], { queryParams: { id: '1234' } });

I had major trouble getting this to work in RCx releases of angular2. The Location package has moved, and running location.go() inside constructor() wont work. It needs to be ngOnInit() or later in the lifecycle. Here is some example code:

import {OnInit} from '@angular/core';
import {Location} from '@angular/common';

@Component({
  selector: 'example-component',
  templateUrl: 'xxx.html'
})
export class ExampleComponent implements OnInit
{
  constructor( private location: Location )
  {}

  ngOnInit()
  {    
    this.location.go( '/example;example_param=917' );
  }
}

Here are the angular resources on the matter: https://angular.io/docs/ts/latest/api/common/index/Location-class.html https://angular.io/docs/ts/latest/api/common/index/LocationStrategy-class.html


I use this way to get it:

const queryParamsObj = {foo: 1, bar: 2, andThis: 'text'};

this.location.replaceState(
  this.router.createUrlTree(
    [this.locationStrategy.path().split('?')[0]], // Get uri
    {queryParams: queryParamsObj} // Pass all parameters inside queryParamsObj
  ).toString()
);

-- EDIT --

I think that I should add some more informations for this.

If you use this.location.replaceState() router of your application is not updated, so if you use router information later it's not equal for this in your browser. For example if you use localizeService to change language, after switch language your application back to last URL where you was before change it with this.location.replaceState().

If you don't want this behaviour you can chose different method for update URL, like:

this.router.navigate(
  [this.locationStrategy.path().split('?')[0]],
  {queryParams: queryParamsObj}
);

In this option your browser also doesn't refresh but your URL change is also injected into Router of your application, so when you switch language you don't have problem like in this.location.replaceState().

Of course you can choose method for your needs. The first is more lighter because you don't engage your application more than change URL in browser.


Use attribute queryParamsHandling: 'merge' while changing the url.

this.router.navigate([], {
        queryParams: this.queryParams,
        queryParamsHandling: 'merge',
        replaceUrl: true,
});