Replies: 4 comments 5 replies
-
I tried the following, seeing if I could get the config object in an injection token, but it didn't work: // inside the app.module.ts
export const APP_CONFIG = new InjectionToken('APP_CONFIG', {
providedIn: 'root',
factory: async () => {
const config = await fetch('/assets/config/config.json')
.then((config) => {
return config.json();
})
.then((config) => {
console.log(config);
});
return config;
},
});
// app.component.ts
constructor(@Inject(APP_CONFIG) private config: any) {}
ngOnInit() {
console.log(this.config);
} The problem is that the console.log just logs this:
|
Beta Was this translation helpful? Give feedback.
-
Some options by using
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app/app.module';
import { CONFIG } from './app/config.token';
fetch('config.json')
.then((res) => res.json())
.then((config) => {
platformBrowserDynamic([
{
provide: CONFIG,
useValue: config,
},
])
.bootstrapModule(AppModule)
.catch((err) => console.error(err));
});
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app/app.module';
import { PlatformRef } from '@angular/core';
import { CONFIG } from './app/config.token';
async function bootstrapWithConfig(
configPath: string,
...args: Parameters<PlatformRef['bootstrapModule']>
) {
const res = await fetch(configPath);
const config = await res.json();
return platformBrowserDynamic([
{ provide: CONFIG, useValue: config },
]).bootstrapModule(...args);
}
bootstrapWithConfig('config.json', AppModule).catch(console.error);
import { CONFIG } from './app/config.token';
import {
ApplicationConfig,
bootstrapApplication,
} from '@angular/platform-browser';
import { AppStandaloneComponent } from './app/app-standalone.component';
async function bootstrapWithConfig(
configPath: string,
...args: Parameters<typeof bootstrapApplication>
) {
const res = await fetch(configPath);
const config = await res.json();
const options: ApplicationConfig = args[1] ?? { providers: [] };
return bootstrapApplication(args[0], {
...options,
providers: [
...options.providers,
{
provide: CONFIG,
useValue: config,
},
],
});
}
bootstrapWithConfig('config.json', AppStandaloneComponent).catch(console.error);
server.get('*', (req, res) => {
res.render(indexHtml, {
req,
providers: [
{ provide: APP_BASE_HREF, useValue: req.baseUrl },
provideConfig(
JSON.parse(
readFileSync(join(__dirname, '../browser/config.json'), {
encoding: 'utf-8',
})
)
),
],
});
});
import { NgModule } from '@angular/core';
import {
ServerModule,
} from '@angular/platform-server';
import { ENVIRONMENT_INITIALIZER, inject } from '@angular/core';
import { CONFIG } from './config.token';
import { AppModule } from './app.module';
import { AppComponent } from './app.component';
export function provideSsrConfig() {
return {
provide: ENVIRONMENT_INITIALIZER,
useValue() {
const config = inject(CONFIG);
const document = inject(DOCUMENT);
const script = document.createElement('script');
script.type = 'text/javascript';
script.text = `
config = ${JSON.stringify(config)}
`;
document.head.insertBefore(script, document.head.firstChild);
},
multi: true,
};
}
@NgModule({
imports: [AppModule, ServerModule],
bootstrap: [AppComponent],
providers: [provideSsrConfig()],
})
export class AppServerModule {}
function bootstrap() {
platformBrowserDynamic([
{
provide: CONFIG,
useValue: (global as any)['config'],
},
])
.bootstrapModule(AppModule)
.catch((err) => console.error(err));
}
if (document.readyState === 'complete') {
bootstrap();
} else {
document.addEventListener('DOMContentLoaded', bootstrap);
} and then you can reference your config in Repo: https://github.com/yharaskrik/angular-load-config-demo |
Beta Was this translation helpful? Give feedback.
-
This is one way I figured out to do it, which is very similar to what is happening now but the config is available as an Injection Token: @yharaskrik what do you think? |
Beta Was this translation helpful? Give feedback.
-
Drive by comment without a whole lot of context, one idea I had some time ago was about having the CLI or Universal write some configuration into the HTML (maybe
My biggest problem with this is just that there's no easy way to make the types sound. You just have to hope the Not sure if that's in line with the direction for this particular library (or even this discussion), but something to think about. |
Beta Was this translation helpful? Give feedback.
-
The benefit of this library is to be able to load config objects that are not needed at build time from an HTTP endpoint or from a JSON file. Thus, feature flags could be turned on/off, API endpoints can be changed, etc. If you use the
environments
file, the value is required at build time and potentially a separate build needs to be done for each environment.Right now, the only way to get the configuration values is to inject the service into your component/service/directive and then use the
getConfigObject
orgetConfigObjectKey
methods. This generally works, but it would be really nice to be able to access the config object in other ways. For example, anInjectionToken
could be created and injected in the desired component:Another great use case is to load the config and be able to use it in the decorator of a module. Something like this:
The
APP_CONFIG.authentication
part is obviously placeholder, and I'm not sure how we would get access to it, but it would be nice. Sometimes these things change (maybe a new scope is added or a callbackUrl is changed) and you don't need to re-build your application. Using some runtime config like this library would be great.The problem is I don't know 1) if any of this is possible, or 2) how to implement it.
I was thinking of trying to create the injection token and have the factory call the load config function; in essence it would look very much like the APP_INITIALIZER does here. Is that possible? What options are available to potentially accomplish the goals listed above? I'm open to suggestions, and PRs/code input as well if you are interested in helping.
Thanks!
Beta Was this translation helpful? Give feedback.
All reactions