Search code examples
angulartypescriptconfigurationproduction

Angular Environment Specific Deployment


I am new to Angular development. I have developed an Angular web application which talks to the back end java application via REST and which in turn talks to the database to perform some CRUD operations.

Angular APP <-> Back end Java <-> DB

In the angular app, I have multiple URL's configured in a typescript file, let's call it app.constants.ts. From my Angular services I read the URL's from app.constants.ts and use it to make a REST call to my back end Java application. I build/compile the angular application using the command ng build --prod, which generates a folder under dist containing index.html, few images, javascript files, and few text files. I then copy this folder to the webapps/deploy folder under Tomcat running on a different server, which will bring up the Angular application, works well!

But my real problem is this,

  1. All the while I have been reading constants from a typescript file and using it to build the application.
  2. Instead of this, I want to have separate configuration files, like one for production, staging, dev, testing and so on.
  3. I want to build the angular application only once and deploy it using the configuration file for that particular environment.
  4. Even if I use multiple typescript files for configuration, this would be used in the compilation of the angular code. Rather, I just want the code complied once with placeholders for configs and use the configs from the right configuration file based on how we deploy the application.

Is this possible? Any information/help would be appreciated. Thank you.

Adding the below code after making it work using APP_INITIALIZER as suggested by @IsraGab file: app-config.service.ts

settings: Config;
load() {
    const jsonFile = './assets/config/config.json';
    return new Promise<void>((resolve, reject) => {
        this.http.get(jsonFile).toPromise().then((response : Config) => {
           this.settings = <Config>response;

           console.log('Config Loaded');
           console.log( this.settings);
           resolve();
           
        }).catch((response: any) => {
           reject(`Could not load the config file`+response);
        });
    });
}

File: app.module.ts

providers: [{ provide: APP_INITIALIZER,useFactory: initializeApp, deps: [AppConfigService], multi: true}]

export function initializeApp(appConfigService: AppConfigService) {
  return (): Promise<any> => { 
    return appConfigService.load();
  }
}
@NgModule

File:mydata.service.ts

protected configURL;
constructor(private apiService: AppConfigService ) { 
    this.configURL = this.apiService.url;
}

Solution

  • You have 2 ways to do it. First of all, let's call your constant file a config file.

    1. First option is to use environment.*.ts files, addapt angular.json and and declare your constants in these files. If you chose that option you would have to run as many build as you have environement (one build for test, one build for production ...).

    2. Second option is to use the APP_INITIALIZER in order to load (http request) a config file - that config file will have the same name, but will be different in each environment (no needs to make a different build in that option).

    Here you can find a tutorial how to use APP_INITIALIZER to load config at run time (Second option)