Change route params without reloading in angular 2

I'm making a real estate website using angular 2, google maps, etc. and when a user changes the center of the map I perform a search to the api indicating the current position of the map as well as the radius. The thing is, I want to reflect those values in the url without reloading the entire page. Is that possible? I've found some solutions using AngularJS 1.x but nothing about angular 2.

Answers:

Answer

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/");
  }
}
Answer

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([{param: 1}], {relativeTo: this.activatedRoute})
        .toString();

 this.location.go(url);
Answer

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

Answer

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' } });
Answer

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.

Answer

For me it was actually a mix of both with Angular 4.4.5.

Using router.navigate kept destroying my url by not respecting the realtiveTo: activatedRoute part.

I've ended up with:

this._location.go(this._router.createUrlTree([this._router.url], { queryParams: { profile: value.id } }).toString())
Answer

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

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

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.

Tags

Recent Questions

Top Questions

Home Tags Terms of Service Privacy Policy DMCA Contact Us

©2020 All rights reserved.