Set up Angular 6 environment variables from .env

11,134

Solution 1

You can create a config file and populate in Run-time.

1) create a File(app-config.json) in assets folder with your variables

{ "servicesUrl": "https://localhost:8080/api"}

2) create a service (AppConfigService ) to read the file.

@Injectable()
    export class AppConfigService {
        private appConfig;

        constructor (private injector: Injector) { }

        loadAppConfig() {
            let http = this.injector.get(HttpClient);

            return http.get('/assets/app-config.json')
            .toPromise()
            .then(data => {
                this.appConfig = data;
            })
        }

        get config() {
            return this.appConfig;
        }

3) Next we need to tell our application to execute the loadAppConfig() method of our service.

import { NgModule, APP_INITIALIZER } from '@angular/core';
import { AppConfigService } from './services/app-config.service';

@NgModule({
   ...,
    providers: [
        AppConfigService,
        {
            provide: APP_INITIALIZER,
            useFactory: appInitializerFn,
            multi: true,
            deps: [AppConfigService]
        }
    ],
    ...
})
export class AppModule { } 

4) create a function called "appInitializerFn" to call our service in AppModule (app.module.ts)

const appInitializerFn = (appConfig: AppConfigService) => {
    return () => {
        return appConfig.loadAppConfig();
    }
};

...

@NgModule({
    ...
})
export class AppModule {}

5) import environment and use it :example

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { AppConfigService } from './services/app-config.service';

@Injectable()
export class DataContextService {
    basePath: string;

    constructor (private environment: AppConfigService, private http: HttpClient) {
        this.basePath = environment.config.servicesBasePath;
    }

    getNames() {
        return this.http.get(this.basePath + '/names/');
    }
}

for more information please see: link

Solution 2

This question becomes also more and more important, when we want to containerize angular applications.

My research lead me to an idea, where I have to write a little node.js or typescript program, using dotenv for reading .env file and create the environment.ts file at buildtime, before starting ng serve. You can create entries in the package.json like this:

...
"config": "ts-node set-env.ts",
"server": "npm run config && ng serve"
...

and run it with

npm run server

Here is a good explanation with an example typescript file: https://medium.com/@ferie/how-to-pass-environment-variables-at-building-time-in-an-angular-application-using-env-files-4ae1a80383c

Share:
11,134
sr9yar
Author by

sr9yar

Roses are red, Violets are blue, Unexpected '}' On line 32.

Updated on June 21, 2022

Comments

  • sr9yar
    sr9yar almost 2 years

    There's an angular 6 project using environment variables from ./project/src/environments/environment.prod.ts

    export const environment = {
      production: true,
      testVar: 'gg',
    };
    

    The backend for this project also has env variables in a .env file, so a lot of variable duplicate angular env variables. It would be nice to have something like

    export const environment = {
      production: true,
      testVar: process.env.TEST_VAR
    };
    

    , so I didn't have to duplicate variables.

    ie

    I'd like to parse variables from a .env file and assign their values to angular env variables during typescript compilation on the server.

    How can this be done? Maybe with webpack?

    UPDATE

    Some clarification. My .env file contains no json. It looks like this:

    TEST_VAR=1
    

    UPDATE

    Since ng eject is not available for Angular 6, I don't seem to be able to hack into webpack config. Looks like deadend here.

    ng eject

    Overview

    Temporarily disabled.

    Ejects your app and output the proper webpack configuration and scripts.

  • sr9yar
    sr9yar over 5 years
    Hi, thanks for your input, but my .env file has no json, and I want to configure it at build time, not at run time.
  • Fernix
    Fernix over 5 years
    have you your backend and front-end in the same project? you could try to reference to another env file
  • sr9yar
    sr9yar over 5 years
    If this is important, they are in different folders on the same machine. In fact, there's several angular apps, running independently and using the same API, also local config, configs for 2 dev servers, prod config. So there's some copypasting happening, hence the question.
  • sr9yar
    sr9yar over 5 years
    Yes.... but it doesn't really run on the server, it actually runs in the browser. :)
  • Fernix
    Fernix over 5 years
    if you want to use procces.env you must run your angular app on node server.
  • Fernix
    Fernix over 5 years
    maybe you can try with Gulp and manage it with gulp-environments
  • Kasir Barati
    Kasir Barati almost 2 years
    Thanks for answer, But I'd like to see something more promising. I do these hack and I am OK with them but as long as I could not find any solution. Do you find a better solution for this issue?