Newer
Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
# Multi-environment docker build for Angular app
As we use docker to deploy our application on different environments, we didn't want to build one image per environment but rather have one image representing a version of the application taking a dynamic configuration.
The default Angular environment system doesn't allow that as the env file is compiled and so has to be defined at build time.
To address this issue we implemented an alternative system that reads the configuration from a config.json file located in the assets folder. This happens at the bootstrap of the application in the user browser.
Here is the corresponding code.
At the bootstrap of the app we fetch the config.json file and set a window variable with the retrieved content.
```
// main.ts
fetch('./assets/config/config.json')
.then(response => response.json())
.then((config) => {
if (!config) {
return;
}
// Store the response so that your ConfigService can read it.
window['adminGuiEnvConfig'] = config;
platformBrowserDynamic().bootstrapModule(AppModule)
.catch(err => console.log(err));
});
```
Then we add a dedicated service `app-config.service.ts` which is added to the `providers` in the app module.
```
// This class describes the configuration of the project
export class AppConfig {
organizations: {
url: string;
};
...
}
// Export the varaible that contains the configuration
export let APP_CONFIG: AppConfig;
@Injectable()
export class AppConfigService {
constructor() { }
// Method that reads the window variable containing the configuration and initialize
// an AppConfig object contained in the export APP_CONFIG variable
public load() {
return new Promise((resolve, reject) => {
const conf = new AppConfig();
APP_CONFIG = Object.assign(conf, window['adminGuiEnvConfig']);
resolve();
});
}
}
```
Add an APP_INITIALIZER that will call the load method when the application starts and so on initialize the configuration.
```
// app.module.ts
export function initAppConfig(appConfigService: AppConfigService) {
return (): Promise<any> => {
return new Promise((resolve, reject) => {
appConfigService.load();
resolve();
});
};
}
@NgModule({
...
providers: [
AppConfigService,
{
provide: APP_INITIALIZER,
useFactory: initAppConfig,
deps: [AppConfigService],
multi: true,
},
],
bootstrap: [AppComponent],
})
```
Import and use the APP_CONFIG in your components, services... when you need it.
```
// Example
import { APP_CONFIG } from './app-config.service';
@Injectable()
export class OrganizationService {
organizationServiceUrl: string;
private _searchChangeSubject: Subject<any>;
constructor() {
this.organizationServiceUrl = `${APP_CONFIG.organizations.url}organizations/`;
}
}
```