Вставить данные, полученные до приложения bootstrap в модуль, импортированный в AppModule - PullRequest
0 голосов
/ 25 февраля 2020

Моя цель: получить данные конфигурации приложения из файла stati c json, а затем внедрить эти данные в сторонний модуль, который я импортирую в мой AppModule.

Я не хочу использовать файлы среды для этой цели, поскольку мне нужно иметь одну сборку для развертывания во всех средах.

Вот что я пробовал:

Main.ts (предоставляет данные конфигурации перед загрузкой приложения, поэтому оно доступно как можно скорее):

import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';

import { APP_CONFIG } from './app/classes/app-config';
import { AppModule } from './app/app.module';
import { environment } from './environments/environment';

fetch('/assets/config.json')
    .then(response => response.json())
    .then(config => {
        if (environment.production) {
            enableProdMode();
        }

        platformBrowserDynamic([{ provide: APP_CONFIG, useValue: config }])
            .bootstrapModule(AppModule)
            .catch(err => console.error(err))
    })

app.module.ts

import { BrowserModule } from '@angular/platform-browser';
import { NgModule, Inject } from '@angular/core';
import { AuthModule, AuthConfig } from 'angular-crb-oauth';
import { AppComponent } from './app.component';
...
import { APP_CONFIG } from './classes/app-config';

@NgModule({
    declarations: [
        AppComponent,
        ...
    ],
    imports: [
        ...
        AuthModule.forRoot(this.config.authSettings) // This does not work - 'this.config' is not recognized here
    ],
    providers: [
        ...
    ],
    bootstrap: [AppComponent]
})
export class AppModule {

    constructor(@Inject(APP_CONFIG) private config: APP_CONFIG) {
        console.log('Config - App module', this.config); // This works just fine!
    }

}

Что работает: Конфигурация доступна уже в конструкторе AppModule и успешно вышла на консоль.

Что не работает: Конфигурация, похоже, не работает доступно в массиве imports в AppModule.

В заключение: Как получить доступ к данным конфигурации в массиве imports, чтобы я мог отправить их в AuthModule.forRoot()?

ОБНОВЛЕНИЕ

Я пробовал решение @AlexK, связанное с здесь: Angular - Использовать динамические c переменные в определении модуля

Код компилируется. Но во время выполнения приложение не bootstrap и в консоли выводится ошибка.

Вот что я сделал:

main.ts

import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';

import { APP_CONFIG } from './app/classes/app-config';
import { AppModule } from './app/app.module';
import { environment } from './environments/environment';

fetch('/assets/config.json')
    .then(response => response.json())
    .then(config => {
        if (environment.production) {
            enableProdMode();
        }

        platformBrowserDynamic([{ provide: APP_CONFIG, useValue: config }])
            .bootstrapModule(AppModule.withConfig(config))
            .catch(err => console.error(err))
    })
import { BrowserModule } from '@angular/platform-browser';
import { NgModule, Inject } from '@angular/core';
import { AuthModule, AuthConfig } from 'angular-crb-oauth';
import { AppComponent } from './app.component';

@NgModule()
export class AppModule {
    static withConfig(config: any): any {
        return {
            ngModule: AppModule,
            declarations: [
                AppComponent,
                ...
            ],
            imports: [
                ...
                AuthModule.forRoot(config.authSettings)
            ],
            providers: [
                ...
            ],
            bootstrap: [AppComponent]
        };
    }
}

Вывод сообщения об ошибке в консоли:

VM1324 polyfills.js:3657 Unhandled Promise rejection: No NgModule metadata found for '[object Object]'. ; Zone: <root> ; Task: Promise.then ; Value: Error: No NgModule metadata found for '[object Object]'.
    at NgModuleResolver.resolve (VM1326 vendor.js:31821)
    at CompileMetadataResolver.getNgModuleMetadata (VM1326 vendor.js:30950)
    at JitCompiler._loadModules (VM1326 vendor.js:36745)
    at JitCompiler._compileModuleAndComponents (VM1326 vendor.js:36728)
    at JitCompiler.compileModuleAsync (VM1326 vendor.js:36690)
    at CompilerImpl.compileModuleAsync (VM1326 vendor.js:87721)
    at compileNgModuleFactory__PRE_R3__ (VM1326 vendor.js:73772)
    at PlatformRef.bootstrapModule (VM1326 vendor.js:74092)
    at VM1325 main.js:1422
    at ZoneDelegate.invoke (VM1324 polyfills.js:3365) Error: No NgModule metadata found for '[object Object]'.
    at NgModuleResolver.resolve (http://localhost:4200/vendor.js:31821:23)
    at CompileMetadataResolver.getNgModuleMetadata (http://localhost:4200/vendor.js:30950:45)
    at JitCompiler._loadModules (http://localhost:4200/vendor.js:36745:53)
    at JitCompiler._compileModuleAndComponents (http://localhost:4200/vendor.js:36728:36)
    at JitCompiler.compileModuleAsync (http://localhost:4200/vendor.js:36690:37)
    at CompilerImpl.compileModuleAsync (http://localhost:4200/vendor.js:87721:50)
    at compileNgModuleFactory__PRE_R3__ (http://localhost:4200/vendor.js:73772:21)
    at PlatformRef.bootstrapModule (http://localhost:4200/vendor.js:74092:16)
    at http://localhost:4200/main.js:1422:10
    at ZoneDelegate.invoke (http://localhost:4200/polyfills.js:3365:26)
api.onUnhandledError @ VM1324 polyfills.js:3657
handleUnhandledRejection @ VM1324 polyfills.js:3681
api.microtaskDrainDone @ VM1324 polyfills.js:3674
drainMicroTaskQueue @ VM1324 polyfills.js:3572

В чем может быть проблема?

...