Get domain name for service in Angular2
I need to make request to same server, REST API on another port.
How can I do this without hardcoding full name in service URLs?
There's no need for an angular2-specific solution. You can use the window.location.hostname
to get the current hostname.
Note, however, if you don't want to use global variables like the window
-object directly, you can provide your own Window
object, which then can be injected.
See this full working Stackblitz Angular sample for details.
Updated Answer for Angular 6+
As others have stated, the original answer does not work anymore. For Angular 6+, you need to provide an Injection Token, so that the window
-object can be resolved in the AOT-build too.
Otherwise you will get the error "Can't resolve all parameters".
I recommend creating a WINDOW_PROVIDERS
array in a separate file like this:
import { InjectionToken, FactoryProvider } from '@angular/core';
export const WINDOW = new InjectionToken<Window>('window');
const windowProvider: FactoryProvider = {
provide: WINDOW,
useFactory: () => window
};
export const WINDOW_PROVIDERS = [
windowProvider
]
The WINDOW_PROVIDERS
constant can be added to the providers
array in the AppModule
like this:
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule
],
providers: [
WINDOW_PROVIDERS, // <- add WINDOW_PROVIDERS here
SampleService,
],
bootstrap: [AppComponent]
})
export class AppModule { }
In the SampleService
, the window
object can be injected by using the defined Injection Token like this:
import { Injectable, Inject } from '@angular/core';
import { WINDOW } from '../window.provider';
@Injectable()
export class SampleService {
constructor(@Inject(WINDOW) private window: Window) {
}
getHostname() : string {
return this.window.location.hostname;
}
}
Original Answer for Angular 2
Therefore you need to set the provider for the Window
-object when bootstrapping your application.
import {provide} from 'angular2/core';
bootstrap(..., [provide(Window, {useValue: window})]);
After that you can use the window object and access the hostname like this:
constructor(private window: Window) {
var hostname = this.window.location.hostname;
}
Another option is to use DOCUMENT from @angular/platform-browser.
import {DOCUMENT} from '@angular/platform-browser';
constructor(@Inject(DOCUMENT) private document: Document) {
let url = document.location.protocol +'//'+ document.location.hostname + ':my_port' );
}
You can use window
, as others have stated, and to make it injectable, from ng6 and forward, you need an injection token.
Declare the token like this:
export const WINDOW = new InjectionToken('window',
{ providedIn: 'root', factory: () => window }
);
Then use it in the class constructor:
class Foo {
constructor(@Inject(WINDOW) private window: Window) { }
}
As Window
is an interface in TypeScript, if you don't do the injection like that, when you build the project for production you will get an error: Can't resolve all parameters for <ClassName>
.
And later another one: ERROR in : Error: Internal error: unknown identifier undefined
.
To understand injection better, read the angular docs for DI: https://angular.io/guide/dependency-injection