How to import .json config to environment.ts and c

2020-07-17 07:25发布

I want to import a Json file which is in assets folder where I have below urls:

config.json:

{
    "url1": "https://jsonplaceholder.typicode.com/posts",
    
    "url2" : "https://reqres.in/api/users",
    
    "url3":"https://fakerestapi.azurewebsites.net/api/Authors"
}

So instead of hard coding the URL, I want to import from Json file, but I am not sure how to do that exactly.

Any suggestions or scenarios would be appreciated, below are my issues:

1. How to import Json file to environment.ts and from there I will have a service which consumes the api

2. If I import the file, it needs to be the same for prod and loc dev also

what I want :

I have a config file where it contains some URL's in .json file stored in asset folder now instead of loading environments.prod or .ts, I want to load my Json file config and basing on that I want to run my application

what I did:

Below is my Json file which I placed in asset folder

{
    "baseUrl": "https://jsonplaceholder.typicode.com/",
    "baseUrl2": "https://reqres.in/api/users"
}

ConfigServiceService.ts for storing config file

public _config: Object;

    constructor(public http:Http) { }
    
    getData(){
       debugger;
       return this.http.get("./assets/config.json").pipe(map(res =>  res.json()));
    }

After this, I create a ServiceProviderService.ts for calling the service file

configData:any;


   constructor(public http:Http,public config:ConfigServiceService) {
    
   }
    
   jsonData(){
       debugger;
       return this.configData;
   }
    
   ngOnInit(){
      debugger;
      this.config.getData().subscribe(res =>{
         console.log(res);
         this.configData = res;
      });
    
    
   }

app.component.ts

 title = 'sample';
 constructor(public serv :ServiceProviderService){
      this.serv.jsonData();
 }

I am not able to get the Json data and if I am putting the logic which is there is ngOnInit in ServiceProviderService.ts file if I put it in constructor then I am getting undefined.

Note : here if there are more than once url then each url is distributed to various seperate service file suppose base1 url for 1 service file ans base2 url for another file how can I achieve that

https://stackblitz.com/edit/read-local-json-file-5zashx

in app.component.ts im getting undefined

enter image description here

8条回答
Explosion°爆炸
2楼-- · 2020-07-17 07:45

I'm not sure if this is the best solution, but here's what I did (by cut'n'pasting what was already in the default Angular project). I had the same goal: I wanted an "API URL" to be available, depending on which environment (Debug or Production) we were using.

First, I added an extra config setting to the two existing .ts files:

  • src\environments\environment.prod.ts
  • src\environments\environment.ts

..so now, each of the files looked something like this:

export const environment = {
  production: false,
  apiUrl: "http://localhost:53104"
};

The main.ts file already has code to read in the environment object, and it uses the environment.production value, so I just added a bit of code to this file to do the same with the environment.apiUrl value:

export function getAPIUrl() {
  console.log("API URL: " + environment.apiUrl);
  return environment.apiUrl;
}

const providers = [
  { provide: 'BASE_URL', useFactory: getBaseUrl, deps: [] },
  { provide: 'API_URL', useFactory: getAPIUrl, deps: [] }
];

. . . 

platformBrowserDynamic(providers).bootstrapModule(AppModule)
   .catch(err => console.log(err));

With this in place, I can access this new "API_URL" value in my components.

For example:

export class FetchDataComponent {
  public forecasts: WeatherForecast[];

  constructor(http: HttpClient, @Inject('BASE_URL') baseUrl: string, @Inject('API_URL') APIUrl: string) {
    http.get<WeatherForecast[]>(baseUrl + 'api/SampleData/WeatherForecasts').subscribe(result => {
      this.forecasts = result;
    }, error => console.error(error));

    console.log("FetchDataComponent, URL: " + APIUrl);
  }
}

When I open this page, I can see my URL shown in the Output window.

FetchDataComponent, URL: http://localhost:53104

Is this solution okay ? It seems a lot simpler (with almost no code) than the other solutions.

Actually, an even simpler solution is to not use a "API_URL" provider, and just stick this in your components:

import { environment } from '../../environments/environment';

..then just access the value using:

console.log("FetchData, URL: " + environment.apiUrl);  

Job done !

查看更多
你好瞎i
3楼-- · 2020-07-17 07:47

You can use required

查看更多
该账号已被封号
4楼-- · 2020-07-17 07:54
    import { environment } from '../../../environments/environment';

    domain :string = environment.domain;

    if(!!environment) {
        if(environment.qa) {
          "url1": "https://jsonplaceholder.typicode.com/posts",
        }
        if(environment.dev) {
           "url2" : "https://reqres.in/api/users",
        } 
      }

you can import the baseUrl property in the asset folder to your service file and execute as I mentioned above.

https://alligator.io/angular/environment-variables/

Please find the url for detailed explanation of environment variables in angular

查看更多
放我归山
5楼-- · 2020-07-17 07:55

You can create constants for all these urls in environment file. I do not see a scenario in your case to put it in a separate json file. For prod, you can use the same environment file by changing default configurations property in angular.json

查看更多
▲ chillily
6楼-- · 2020-07-17 07:57

So, I would create a node script called populatedDynamicUrls.js that can read those values IN from the json file, and write those values OUT to the corresponding environment.ts file for that specific environment. THEN your angular build command would look like this: node populateDynamicUrls.js && ng run build, and your angular serve command would look like this: node populateDynamicUrls.js && ng run serve

查看更多
我想做一个坏孩纸
7楼-- · 2020-07-17 08:04

If you want to import json file

  1. Add config.json to the assets directory.
  2. Edit typings.d.ts file:
    declare module "*.json" {
        const value: any;
        export default value;
    }
  1. Add path of typings.d.ts to "typeRoots" in tsconfig.json, for example:
"typeRoots": [
      "node_modules/@types", "./src/typings.d.ts"
],
  1. Import config.json in environment file:
import * as config from '../assets/config.json';

export const environment = {
  baseUrl: config.default.url1
  production: true
};

That's all, good luck!

查看更多
登录 后发表回答