30

Wondering if there is a way to retrieve full url for a given route?

In Angular app you might use router.navigate('...') which will immediately navigate your browser to given route, but is there a way just to build URL string?

Use case for this is communication with 3rd party services like OAuth2 where I need to provide callback url, I wish not to build it by hands but call something like router.urlFor('callback') which will produce something like "http://localhost:4200/callback"

There is Location service which has prepareExternalUrl but unfortunately it is not what is needed

Edit:

At moment seems that it is not possible and there is no easy out of the box solution, but after looking around at sources find following solution:

const urlTree = router.createUrlTree(['callback'], {
    queryParams: { foo: 'bar' },
    fragment: 'acme'
});
const path = location.prepareExternalUrl(urlTree.toString());
const url = window.location.origin + path;
console.log(url); // http://localhost:4200/callback?foo=bar#acme

createrUrlTree is being called underneath routerLink directive

Martin Brisiak
  • 3,872
  • 12
  • 37
  • 51
mac
  • 1,119
  • 2
  • 14
  • 13
  • Have you tried [this](https://angular.io/guide/router#activated-route)? – nightElf91 Dec 03 '17 at 10:52
  • 1
    @NishadAhsan [ActivatedRoute](https://angular.io/api/router/ActivatedRoute) - contains the information about a route associated with a component loaded in an outlet. In other words *ActivatedRoute* may be used to get info about current route not for generating urls – mac Dec 04 '17 at 11:23
  • Do you like any of the answers? Would you pick one and mark it as the right one? Thanks! – Janos Vinceller Dec 10 '20 at 11:51

7 Answers7

7

You could try this :

import { Component } from '@angular/core';
import { Router } from '@angular/router';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent {
  title = 'stackoverflow';
  constructor(private router: Router) {
    console.log(this.router['location']._platformLocation.location.origin);
    // result: http://localhost:4200
  }
}
Kirill Rakhman
  • 42,195
  • 18
  • 124
  • 148
Behram Bazo
  • 230
  • 2
  • 6
  • 1
    `.origin` will not help if user on certain page - lets say on http://localhost:4200/details. In this case I would go with `href`. I.E `this.router['location']._platformLocation.location.href` – Jviaches Oct 19 '22 at 00:14
2

You can get baseurl with the following code on javascript

const parsedUrl = new URL(window.location.href);
const baseUrl = parsedUrl.origin;
console.log(baseUrl);

and then concatenate it with for example /callback to make

http://localhost:4200/callback
Martin Brisiak
  • 3,872
  • 12
  • 37
  • 51
Behnam Aminazad
  • 411
  • 2
  • 5
  • 19
1

There is a "correct" way to build a full url, which can be found in RouterLink directive sources https://github.com/angular/angular/blob/main/packages/router/src/directives/router_link.ts#L331

constructor(
  private locationStrategy: LocationStrategydo injections
) {}
...
const fullUrl = this.locationStrategy.prepareExternalUrl(this.router.serializeUrl(this.urlTree))

or just 
const fullUrl = this.locationStrategy.prepareExternalUrl('/internal/path')


Andrei
  • 10,117
  • 13
  • 21
0

You're usually configuring your base URL somewhere, e.g. in a yaml file. This way you can configure all your different stages (component test, integration test, additional test, production). At runtime you would read the configuration and use some kind of a utility method or just string concatenation to produce your taget URL.

I would not parse the location.href property, because you're often behind a load balancer, a reverse proxy, so you don't know what exactly to add to your base URL. For simple apps it might be enough though.

Here an example:

Your local URL: http://localhost:8080/myapp/somefunction Your production URL: https://www.somecompany.com/itdepartment/myapp/somefunction

Janos Vinceller
  • 1,208
  • 11
  • 25
0

I thinks you make mistake to handle oauth2. for oauth2 1- frontend request api to login and then api redirect it to external oauth2 server. 2-then after login oauth2 server redirect you to api callback(that it is specified in oauth2 server as returnUrl). 3- api server redirect browser to frontend application. so when frontend call api server to login just set querystring returnUrl( value of that is current page route so it is location.href) at url and send it to api then api will be save it and in api callback api will rediret client to previous saved Url.

-1

Can you do something list this to get the list of urls and send the ones you want? ```

import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { environment } from 'src/environments/environment';


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

  constructor(private router: Router) { }
  urls: string[] = [];

  ngOnInit() {

    this.router.config.forEach(r => {
      console.log(r)
      this.urls.push(this.buildUrl(r.path));
    })
  }

  buildUrl(path: string) {
    return `${environment.basePath}/${path}`
  }

}

```

Mike
  • 607
  • 8
  • 18
-1

You can fetch full route URL and in segment too. Use the following code:

    import { Component, OnInit } from '@angular/core';
    import { Router, ActivatedRoute } from '@angular/router';
    
    @Component({
      selector: 'app-hero',
      templateUrl: './hero.component.html',
      styleUrls: ['./hero.component.css']
    })
    export class HeroComponent implements OnInit {
    
      constructor(private router: Router,  private activeRoute: ActivatedRoute) { 
        this.activeRoute.queryParams.subscribe((qp) => {
          console.log('Get Router URL in segment:', this.activeRoute.snapshot);
          console.log('Get Full Router URL:', this.router.url);
        });
      }
    
      ngOnInit(): void {
      }    
    }

For more information check out this link

Salahuddin Ahmed
  • 4,854
  • 4
  • 14
  • 35
KK Nebula
  • 121
  • 1
  • 2