I have added AngularFire to my project. In its readme I was instructed to add the AngularFireModule.initializeApp(...) to the imports of my AppModule
In examples people use the environment constant, however, that is not an option because Deployment requires that there be a config file where it would then substitute variables when it deploys depending on the environment it deploys to.
I believe my config is loaded after the imports which means nothing is passed to the .initializeApp(...)
app.module.ts
import { AngularFireModule } from '@angular/fire';
import { AngularFireAuthModule } from '@angular/fire/auth';
...
export function initializeApp(appConfig: AppConfig) {
return () => appConfig.load();
}
@NgModule({
declarations: [
AppComponent
],
imports: [
...,
AngularFireModule.initializeApp(AppConfig.firebase),
AngularFireAuthModule
],
providers: [
AppConfig,
{ provide: APP_INITIALIZER, useFactory: initializeApp, deps: [AppConfig], multi: true },
...,
],
bootstrap: [AppComponent]
})
export class AppModule { }
app-config.ts
import { Injectable } from '@angular/core';
import { AppConfigModel } from './shared/models/app-config.model';
import { HttpClient } from '@angular/common/http';
import { environment } from '../environments/environment';
/**
* This config pattern based off https://devblogs.microsoft.com/premier-developer/angular-how-to-editable-config-files/
* which is referenced in Octopus Deploy blog here https://octopus.com/blog/javascript-configuration
*/
@Injectable()
export class AppConfig extends AppConfigModel {
constructor(private http: HttpClient) {
super();
}
/**
* Loads the required config file from assets, depending on configName of environment.
* This allows replacement of variables by Octopus Deploy
*/
public load() {
const jsonFile = `assets/config/config.${environment.configName}.json`;
return new Promise<void>((resolve, reject) => {
this.http.get(jsonFile).toPromise().then((response: AppConfigModel) => {
this.mapConfigToProperties(response);
resolve();
}).catch((response: any) => {
console.error('On config load', response);
reject(`Could not config load file '${jsonFile}': ${JSON.stringify(response)}`);
});
});
}
private mapConfigToProperties(config: any) {
Object.keys(config).forEach(key => {
AppConfig[key] = config[key];
});
}
}
I would very much like to get this solved without having to change any build processes and simply being able to to use the AppConfig to retrive the config.
package.json
{
...,
"dependencies": {
"@angular/animations": "^6.1.10",
"@angular/cdk": "^6.3.0",
"@angular/common": "^6.0.3",
"@angular/compiler": "^6.0.3",
"@angular/core": "^6.0.3",
"@angular/fire": "^5.3.0",
"@angular/forms": "^6.0.3",
"@angular/http": "^6.0.3",
"@angular/platform-browser": "^6.0.3",
"@angular/platform-browser-dynamic": "^6.0.3",
"@angular/router": "^6.0.3",
"core-js": "^2.5.4",
"firebase": "^7.7.0",
"moment": "^2.24.0",
"ng-pick-datetime": "^6.0.16",
"ng-pick-datetime-moment": "1.0.7",
"ngx-image-cropper": "^2.0.2",
"ngx-smart-modal": "^7.1.1",
"ngx-textarea-autosize": "^2.0.3",
"ngx-toastr": "^10.0.4",
"rxjs": "6.3.3",
"zone.js": "^0.8.26"
},
...
}
main.ts
import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app/app.module';
import { environment } from './environments/environment';
import { FirebaseOptionsToken, AngularFireModule } from '@angular/fire';
if (environment.production) {
enableProdMode();
}
platformBrowserDynamic().bootstrapModule(AppModule)
.catch(err => console.log(err));
This can be achieved by providing parameters to the
platformBrowserDynamic(...)which takes an array of providers similar to the array in theprovidersproperty of@NgModule.We will solve this by using this parameter. We will feed in the parameter for the firebase config and then remove it from the import in the AppModule.
main.ts
app.module.ts
This answer was inspired by AngularFire2 App Init in Module Conflicts with Dynamic Config Data
Additional reading on providers and angular dependency injection, link