1

I'm developing an application and am unsure about where it will be deployed. I need to be able to have the application routes prepended dynamically from the prefix in an external settings file.

We're working in a test environment where it's being deployed to a sub location. However, when we attempt to navigate to hostname/sublocation, all the routes fail because it's attempting to use the root location (which is unavailable to us).

I've designed an app.config.json file with a location_prefix setting, and have created a service that's loaded using the APP_INITIALIZER in the app.module. However, it's returning an error saying that it Cannot read property 'location_prefix' of undefined.

We've also verified the server configuration and have confirmed that it's setup up properly.

config-loader.json

/** Loader for configuration file values */
@Injectable()
export class ConfigLoader {

    /** Application configuration */
    static configuration: ConfigFile;

    /** Initializes a new instance of the {@link ConfigLoader} class */
    constructor(private httpClient: HttpClient) { }

    load() {
        const configUrl = 'app.config.json';

        return new Promise<void>((resolve, reject) => {
            this.httpClient.get(configUrl).toPromise().then((config: ConfigFile) => {
                ConfigLoader.configuration = config;
                resolve();
            }).catch(reason => {
                reject(`Unable to load settings file '${configUrl}': ${JSON.stringify(reason)}`);
            });
        });
    }
}

app.module.ts:

@NgModule({
  declarations: [...],
  imports: [
    AppRoutingModule,
    ...
  ],
  providers: [
    ConfigLoader,
    {
      provide: APP_INITIALIZER,
      useFactory: (configLoader: ConfigLoader) => configLoader.load(),
      deps: [ConfigLoader], multi: true
    }
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }

app.routing.module

const prefix = ConfigLoader.configuration.location_prefix;
const routes: Routes = [
  { path: prefix, redirectTo: `${prefix}landing-page`, pathMatch: 'full' },
  { path: `${prefix}landing-page`, component: LandingPageComponent }
];

@NgModule({
      imports: [RouterModule.forRoot(routes)],
      exports: [RouterModule]
    })
export class AppRoutingModule {
}

I'm expecting to be able to navigate to hostname/sublocation and see the primary route. Again, I'm getting an error because the ConfigLoader.configuration isn't being populated before the Router is configured.

bvanfleet
  • 19
  • 4
  • Welcome to stackoverflow! Have you seen the discussion about this here: https://stackoverflow.com/questions/38112891/angular-2-4-5-set-base-href-dynamically – DeborahK Jan 22 '19 at 22:30
  • After manually modifying the files last night (to get this ready for a demo) I noticed the base-href. I'll check into that discussion, but have high hopes. Thanks! – bvanfleet Jan 24 '19 at 01:13
  • I've been working with Angular2+ since 2015. How am I just now learning about the `APP_INITIALIZER`. This solves SO many problems. – mwilson Jan 09 '20 at 17:11

0 Answers0