How to Configure Dynamic Environment in angular

I usually do “.environment.ts” files to set environments. When i build the code I do 3 builds those are dev, test and production. Single build is not possible for all environments i did two approaches to set environments. I will explain both here.

Method 1:

If you know your Test, Dev and production URLs before build you use this method. This is Static one. First Create a project using below command.

ng new dynamic-envs

Go to newly created project and Create a static service using below command

ng g s services/env1

Then Identify the current url and set your environment according to that.

import { Injectable } from '@angular/core';
import {PlatformLocation } from '@angular/common';

@Injectable({
  providedIn: 'root'
})
export class Env1Service {

  constructor(public platformLocation: PlatformLocation) { }

  getEnv() {
    /**  Identify current url */
    const currentURL = (this.platformLocation as any).location.origin;
    /** set envronment default dev */
    let envs = {apiURL: 'http://dev.com', mode: 'dev'};

    /** I assumed my current url is related to test I set my Test envronments. Do for production also same */
    if (currentURL === 'http://localhost:4001') {
      envs.apiURL = 'http://test.com',
      envs.mode = 'Test';
    } else if (currentURL === 'http://localhost:4002') {
      envs.apiURL = 'http://prod.com',
      envs.mode = 'Production';
    }
    return envs;
  }
}

Inject this service what ever you want and use “getEnv()” function for identify the environment.

export class AppComponent implements OnInit {
  title = 'dynamic-envs';
  apiURL1: string;
  mode1: string;
  constructor(private env1: Env1Service) { }

  ngOnInit() {
    /* First Method */
    const getData = this.env1.getEnv();
    this.apiURL1 = getData.apiURL;
    this.mode1 = getData.mode;
  }
}

Method 2:

This is little bit complex but dynamic one. First you Create “envronments.json” file in assets file.

{
“apiURL”: “http://dev.com”,
“mode”: “Development”
}

Create a service using below command

ng g s services/env2

Load Environment Variables from Json File

import { Injectable } from '@angular/core';
import {HttpClient} from '@angular/common/http';
import {Observable} from 'rxjs';
import {shareReplay} from 'rxjs/operators';

interface Envronment {
  apiURL: string;
  mode: string;
}

@Injectable({
  providedIn: 'root'
})
export class Env2Service {

  private readonly ENV_URL = 'assets/envronments.json';
  public Envronment$: Observable<Envronment>;

  constructor(private http: HttpClient) {
  }

  public loadEnvronments(): any {
    if (!this.Envronment$) {
      this.Envronment$ = this.http.get<Envronment>(this.ENV_URL).pipe(
        shareReplay(1)
      );
    }
    return this.Envronment$;
  }

}

Initialize this service in app.module.ts file

import { BrowserModule } from '@angular/platform-browser';
import { NgModule, APP_INITIALIZER } from '@angular/core';
import { HttpClientModule } from '@angular/common/http';
import { AppComponent } from './app.component';
import { Env1Service } from './services/env1.service';
import { Env2Service } from './services/env2.service';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    HttpClientModule
  ],
  providers: [
    Env1Service,
    {
      provide: APP_INITIALIZER,
      useFactory: (Env2Service: Env2Service) => () => Env2Service.loadEnvronments().toPromise(),
      deps: [Env2Service],
      multi: true
    }
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }

Use this service like below.

import { Component, OnInit } from '@angular/core';
import { Env1Service } from './services/env1.service';
import { Env2Service } from './services/env2.service';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
  title = 'dynamic-envs';
  apiURL1: string;
  mode1: string;
  apiURL2: string;
  mode2: string;
  constructor(private env1: Env1Service, private env2: Env2Service) { }

  ngOnInit() {
    /* First Method */
    const getData = this.env1.getEnv();
    this.apiURL1 = getData.apiURL;
    this.mode1 = getData.mode;

    /* second Method */
    this.env2.Envronment$.subscribe(res => {
      this.apiURL2 = res.apiURL;
      this.mode2 = res.mode;
    });
  }
}

After build you change your “envronments.json” file according to your environment.

Git Link: https://github.com/iamchandu/dynamic-envs-angular

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

Create your website with WordPress.com
Get started
%d bloggers like this: