Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

createUrlTree ignores "useHash: true" RouterModule configuration

In Angular 7 single page app with "useHash: true" Router module configuration I need to generate url to a resource to be opened in a new tab.

For routing in the app window following code works as expected:

this.router.navigate(['foo', 1]);

That means, it generates url like: http://localhost:4200/#/foo/1

Although when using following method: const url = this.router.createUrlTree(['foo', 1]).toString();

url is "/foo/1" - without the "#", so...

window.open(url, '_blank'); result with NOT valid url:

http://localhost:4200/foo/1

The only solution (hack) i found is quite brutal:

window.open('#' + url, '_blank');

RouterModule.forRoot(routes, {
  useHash: true,
  onSameUrlNavigation: 'reload',
}
showItem(item: Item) {
  // THIS WORKS AS EXPECTED
  this.router.navigate(['item', item.id]);
}

showItemInNewTab(item: Item) {
  const url  = this.router.createUrlTree(['item', item.id]).toString();

  // THIS WORKS BUT ITS A HACK :/
  window.open('#' + url, '_blank');
}
like image 883
Maciek Zych Avatar asked Jun 27 '19 14:06

Maciek Zych


1 Answers

Apparently the Location class in @angular/common can help you resolve this:

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

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent implements OnInit {

  constructor(
    private _urlSerializer: UrlSerializer,
    private _location: Location,
    public router: Router) {
  }

  ngOnInit() {
    let tree = this.router.createUrlTree(['/profile']);
    // The call to Location.prepareExternalUrl is the key thing here.
    console.log(this._location.prepareExternalUrl(this._urlSerializer.serialize(tree)));
    // As far as I can tell you don't really need the UrlSerializer.
  }
}

When I tested this it respects the router's useHash setting.

like image 113
Paul Wheeler Avatar answered Sep 27 '22 18:09

Paul Wheeler