38666
Angular4でアプリで外だしのファイルで設定値などを変えたいです。  
（説明が下手で申し訳ないです…）

<https://stackoverflow.com/questions/46001669/blank-page-except-index-html-
with-angular-4-in-tomcat-environment>  
ng build --prod --aot=false --output-hashing=none --base-href=/Test/  
その後、webappsへ配置してみると以下へのアクセスで画面表示が可能でした。  
ビルド結果は以下のような形になっていました。

```

    \webapps\Test\assets
    \webapps\Test\3rdpartylicenses.txt
    \webapps\Test\favicon.ico
    \webapps\Test\index.html
    \webapps\Test\inline.bundle.js
    \webapps\Test\main.bundle.js
    \webapps\Test\polyfills.bundle.js
    \webapps\Test\styles.bundle.css
    \webapps\Test\vendor.bundle.js
    
```

そこで以下にsettingファイルなどを置き、こちらの設定値を書き換えることで、  
ビルドしなおさなくても取得できるようにしたいのですが、  
どのようにするのが一般的でしょうか？（そもそもできるのでしょうか？）

```

    \webapps\Test\setting.???
    
```

◆追記  
shimiteiさまのご回答から以下を追加しました。  
◇config.service.ts

```

    import { Injectable } from '@angular/core';
    import { Http } from '@angular/http';
    import 'rxjs/add/operator/map';
    
    @Injectable()
    export class ConfigService {
        config: any;
        constructor(private http: Http) { }
    
        // public getConfig(key: any) {
        //     return this.config[key];
        // }
        public getConfig(key: any) {
            if (!Array.isArray(key)) {
                return this.config[key];
            }
            let res: any = this.config;
            key.forEach(k => res = res[k]);
            return res;
        }
    
        load() {
            return new Promise((resolve) => {
                this.http.get('config.json')
                    .map(res => res.json())
                    .subscribe(json => {
                        this.config = json;
                        resolve();
                    });
            });
        }
    }
    
```

◇config.json  
※src直下に配置

```

    {
      "testFlag": false
    }
    
```

◇app.module.ts  
回答いただいた内容を追加

呼び出したい箇所で以下を実施。

```

    this.configService.getConfig("キー");
    
```

すると、ConfigServiceのload()が呼ばれることは確認できたのですが、  
config.jsonがstatus: 404, statusText: "Not Found"で怒られてしまいます。  
ためしに「assets」の下にjsonを持っていき、

```

    this.http.get('assets/config.json')
    
```

と変えてみましたが、同じようにエラーとなってしまいました。  
jsonファイルを配置する箇所に制限があったりするのでしょうか？

◆さらに修正  
★箇所にて  
「core.es5.js:1020 ERROR SyntaxError: Unexpected token / in JSON at position
4」が出てしまいました。

JSONにコメントを入れていたことが原因のようです。コメントを削除し、以下のようにしました。  
それで無事取得できました！

```

    this.config = response.json() as ConfigData;
    
```

◇config.data.ts

```

    export class ConfigData {
        constructor(private testFlag: boolean) {
        }
    }
    
    export class ConfigService {
        config: any;
        constructor(private http: Http) { }
    
        public getConfig(key: any) {
            if (!Array.isArray(key)) {
                return this.config[key];
            }
            let res: any = this.config;
            key.forEach(k => res = res[k]);
            return res;
        }
    
        load() {
            return new Promise((resolve) => {
                this.http.get('assets/config.json')
                    .subscribe(response => {
                        this.config = response.json() as ConfigData;
                        resolve();
                    });
            });
        }
    }
    
```
CC BY-SA 3.0
2017-10-13T00:37:31.993
38653
2017-10-17T04:32:49.273
2017-10-17T04:32:49.273
12842
12842
question
angular4
Angular4でアプリで外だしのファイルで設定値などを変えたい
JavaScript、TypeScriptではJSON形式のデータが扱いやすいです。  
setting.json等のJSON形式データのファイルを置いてアプリの実行時に読み出して使います。

AngularではHttpモジュールにHTTP通信機能があり、これを使って設定データを取得します。  
※HttpモジュールはEXPERIMENTAL扱いのため、Angular
4.3以降では新しい[HttpClientモジュール](https://angular.io/api/common/http/HttpClient)を使うと良いです。

データ取得は非同期に行われるため、設定データが未取得か取得済みかを考慮するとややこしくなります。  
アプリの起動時の初期化のタイミングで何かを処理させる方法も用意されているので、この初期化時に設定データの取得を行うと単純な処理で済みます。

具体的なコードはQiitaにまとめています。  
<https://qiita.com/shimitei/items/19beda3980be61736eef>  
Angular CLI 1.0.0-beta.21、Angular2.2.1の頃のものですが、最近のAngular CLI 1.4、Angular
4.4でも動作しています。

抜き出すと、JSONデータの読み出しと保持するConfigServiceを作成し、設定を参照するコンポーネントはこれをDIします。

```

    import { Injectable } from '@angular/core';
    import { Http } from '@angular/http';
    import 'rxjs/add/operator/map';
    
    @Injectable()
    export class ConfigService {
      config: any;
      constructor(private http: Http) { }
    
      load() {
        return new Promise((resolve) => {
          this.http.get('config.json')
            .map(res => res.json())
            .subscribe(json => {
              this.config = json;
              resolve();
            });
        });
      }
    }
    
```

app.module.tsにアプリ初期化時の処理（APP_INITIALIZER）を追加し、設定データの取得を行います。

```

    NgModule({
      ...
      providers: [
        ConfigService,
        {
          provide: APP_INITIALIZER,
          useFactory: configFactory,
          deps: [ConfigService],
          multi: true
        },
      ],
      ...
    })
    
    export function configFactory(cs: ConfigService) {
      return () => cs.load();
    }
    
```

Angularの作法に沿った方法はこうなります。
CC BY-SA 3.0
2017-10-13T04:37:49.070
38666
2017-10-13T04:37:49.070
3655
38653
answer