1

In Angular2, I have something like templateUrl = 'templates/app.component.html' during development. But in deployment, i need the url to be something like templateUrl = '/static/angular_templates/app.component.html'. It bites to have to change the url at every single place. Is there an easy way to set a base url and do something like

templateUrl = BASE_TEMPLATE_PATH+ '/app.component.html'

so i only need to update BASE_TEMPLATE_PATH when switching from development to production? Thanks!

totoro
  • 3,257
  • 5
  • 39
  • 61

5 Answers5

2

With TypeScript you can use static variables, like :

export class AppTemplateConstants {

    public static get BASE_TEMPLATE_PATH(): string { return 'YOUR_PATH_HERE'; }

}

To import this :

import { AppTemplateConstants } from '../shared/constants/AppTemplateConstants';

To use this :

templateUrl: AppTemplateConstants.BASE_TEMPLATE_PATH + 'app/path/component.html'
AdrienTorris
  • 9,111
  • 9
  • 34
  • 52
  • 2
    Isn't it rather: `AppTemplateConstants.BASE_TEMPLATE_PATH`, @Adrien? :-) – Thierry Templier Apr 22 '16 at 15:53
  • 1
    Hum, you're right ... :) I edited my answer to fix this mistake. Thank's for the notice. – AdrienTorris Apr 25 '16 at 08:55
  • Doesn't seem to work : Error: TypeError: Cannot read property 'BASE_TEMPLATE_PATH' of undefined(…) I tried console.log in the export and I can see the string, but not in the @component – Steven Jun 22 '16 at 20:17
  • @AdrienTorris I get the same error: Uncaught TypeError: Cannot read property 'AppTemplateConstants' of undefined – Eric Bergman Jan 23 '18 at 19:58
  • This won't work with newer Angular versions. `templateUrl` will be replaced by a require call by angular cli internally. The require argument must be a string literal. Otherwise webpack cannot resolve the dependency. (Yes, the template is in fact a dependency like other imports later) – fishbone Aug 22 '18 at 06:35
2

You can achieve the desired effect without changing the templateUrl all over your code base by using UrlResolver, available since 2.0.0-alpha.36.

import {UrlResolver} from '@angular/compiler';
import {NgModule} from '@angular/core';
import {BrowserModule} from '@angular/platform-browser';
import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';

let MyApp: any;

@NgModule({
  imports: [BrowserModule],
  providers: [{provide: UrlResolver, useValue: new UrlResolver("http://localhost/app")}],
  bootstrap: [MyApp]
})
class AppModule {
}

export function main() {
  platformBrowserDynamic().bootstrapModule(AppModule);
}

This will bootstrap your application with a custom instance of UrlResolver that has a base url that you specify. You can even have finer control over resolving the paths by extending the UrlResolver class:

class MyUrlResolver extends UrlResolver {
  resolve(baseUrl: string, url: string): string {
    // Serve CSS files from a special CDN.
    if (url.substr(-4) === '.css') {
      return super.resolve('http://cdn.myapp.com/css/', url);
    }
    return super.resolve(baseUrl, url);
  }
}

@NgModule({
  imports: [BrowserModule],
  providers: [{provide: UrlResolver, useClass: MyUrlResolver}],
  bootstrap: [MyApp]
})
...

(source)

Note: for this to work, you most likely need to use component-relative paths by providing moduleId: module.id, in your component definition, e.g.:

@Component({
    moduleId: module.id,  // use component-relative paths
    selector: 'dialogs',
    templateUrl: './dialogs.html',
})
Dmitry Pashkevich
  • 13,431
  • 9
  • 55
  • 73
1

I use DependencyInjection to pass around an EnviromentSettings object where I store environment variables such as BASE_TEMPLATE_PATH.

Kind of simple and nice mechanism in my opinion.

I hope it helps

Picci
  • 16,775
  • 13
  • 70
  • 113
0

You should define a constant in your build environment, using webpack, for example, you can use the webpack.DefinePlugin: Passing environment-dependent variables in webpack

Community
  • 1
  • 1
Hitmands
  • 13,491
  • 4
  • 34
  • 69
0

you can use one common class/service in which you can store all your global variables and inject that class at the time of bootstrapping by doing so that class is now available to all another classes/components throughout the app and also now you can easily change your variable value by just changing at one place instead of making changes in all components here is example of same -

import {Component, Injecable} from 'angular2/core';

@Injecable()
export class GlobalService {
public BASE_TEMPLATE_PATH: string;

    constructor() {
        this.BASE_TEMPLATE_PATH = "Your Path Goes Here";
    }
}

and just register this service class in bootstrap like this -

bootstrap(AppComponent, [
  HTTP_PROVIDERS,GlobalService , XYZ...
]);

Now this GlobalService class is available to all another classes,

also now no need to register this class in the list of providers every time when you use because angular itself initialize this to all components, Now use these global variables/function in any class like this -

import {GlobalService} from './GlobalService';
...// stuff here
templateUrl: GlobalService.BASE_TEMPLATE_PATH + 'app/path/component.html'
Pardeep Jain
  • 84,110
  • 37
  • 165
  • 215