7

I am working on an angular 7 project which needs to be running on different servers. I need to read server URL from environment file and cannot set as a static variable.

I tried reading a JSON file but as soon as I ng build the project, it copies the content of JSON as static value in main.js

Is it possible to read a JSON file dynamically after building the project? Like reading from env.json which I can put after building the project

Ashutosh
  • 4,371
  • 10
  • 59
  • 105

4 Answers4

3

I created a setting.json file in assets folder, after ng build I go to setting.json change back end url.

export class SettingService  {

  constructor(private http: HttpClient) {

  }

  public getJSON(file): Observable<any> {
      return this.http.get("./assets/configs/" + file + ".json");
  }
  public getSetting(){
      // use setting here
  }
}

In app folder, i add folder configs/setting.json

Content in setting.json

{
    "baseUrl": "http://localhost:52555"
}

In app module add APP_INITIALIZER

 {
      provide: APP_INITIALIZER,
      useFactory: (setting: SettingService) => function() {return setting.getSetting()},
      deps: [SettingService],
      multi: true
    }
Hien Nguyen
  • 24,551
  • 7
  • 52
  • 62
2

With the help of Hien Ngyuen's answer, I did this:

Added following service:

config.service.ts

import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import { Injectable } from '@angular/core';
import { HttpService } from './http.service';
import { ConstantService } from './constant.service';

@Injectable({
   providedIn: 'root'
})
export class ConfigService {
  constructor(
   private httpService: HttpService,
   private constantService: ConstantService
) { }

/*
 *  Load configuration from env.json
 */
loadConfig(): Observable<any> {
   let url = './assets/env.json';

   let requestObject = {
     API_URL: url,
     REQUEST_METHOD: this.constantService.REQUEST_METHOD_GET
   };

   return this.httpService.sendRequest(requestObject).pipe(map(this.extractData));
}

/*
*  Extract data from response
*/
private extractData(res: Response) {
   let body = res;
    return body || {};
}
}

http.service.ts

import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';

import { ConstantService } from './constant.service';

const httpOptions = {
  withCredentials: true,
  headers: new HttpHeaders({ 'Content-Type': 'application/json' })
};

@Injectable({
  providedIn: 'root'
})
export class HttpService {
  constructor(
    private httpClient: HttpClient,
    private constantService: ConstantService
  ) { }

  sendRequest(requestData) {
    if (requestData.REQUEST_METHOD == this.constantService.REQUEST_METHOD_GET) {
      return this.httpClient.get(url, httpOptions);
    } else if (requestData.REQUEST_METHOD ==     this.constantService.REQUEST_METHOD_POST) {
      return this.httpClient.post(url, requestData.BODY, httpOptions);
    } else if (requestData.REQUEST_METHOD == this.constantService.REQUEST_METHOD_PUT) {
      return this.httpClient.put(url, requestData.BODY, httpOptions);
    } else if (requestData.REQUEST_METHOD == this.constantService.REQUEST_METHOD_DELETE) {
      return this.httpClient.delete(url, httpOptions);
    }
  }
}

Next, after ng build I added assets\env.json and I was able to change and read values from env.json.

Ashutosh
  • 4,371
  • 10
  • 59
  • 105
0

No i think you have to maintain a .json file in your code and pick dynamically from it on the basis of your root url. Also you can send a call to server returning base_url each time depending upon the ip or domain from where the request originates.

{
    'server-one': 'abc.com',
    'server-two': 'abc1.com',
}
0

As far as I understand you want to mock backend requests with JSON Files? For me the best way is to use an interceptor, which intercepts the url.

@Injectable()
export class MockResponseInterceptor implements HttpInterceptor {
    constructor() { }

    intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
        // ignore "production" and requests to other ressources
        if (environment.production || !req.url.startsWith(environment.backendBaseUrl)) {
            return next.handle(req);
        }

        const modifiedUrl: string = this.mockUrl(req.url);
        const modifiedRequest = req.clone({ url: modifiedUrl });

        return next.handle(modifiedRequest);
    }

    mockUrl(url: string): string {
      // any kind of modification or replacement etc. goes here
      // you want to return the path to the JSON file here
    }
}
MoxxiManagarm
  • 8,735
  • 3
  • 14
  • 43