1

I've seen this post about setting base href dynamically, but it's kind of pre-defined base href for each customer. In my case, I'd like to generate a random string as base href when a user accesses the web app. For example:

http://localhost:4200/{random-string}/home

http://localhost:4200/{random-string}/home

Understand that the base href can be set like this:

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { APP_BASE_HREF, Location } from '@angular/common';

import { AppComponent } from './';
import { getBaseLocation } from './shared/common-functions.util';

@NgModule({
  declarations: [AppComponent],
  imports: [
    BrowserModule,
    HttpModule,
  ],
  bootstrap: [AppComponent],
  providers: [
    appRoutingProviders,
    {
        provide: APP_BASE_HREF,
        useFactory: getBaseLocation,
        deps: [MyService] // Updated based on @Yakov Fain's comment
    },
  ]
})
export class AppModule { }

{random-string} should be generated in getBaseLocation function, but I need to save this {random-string} within the session for future use, so I saved the {random-string} to a shared service which is injected to the getBaseLocation like this:

export function getBaseLocation(globalService: MyService) {
    let paths: string[] = location.pathname.split('/').splice(1, 1);
    if (paths && paths[0]) {
        // path contains the appId
        console.log("Existing appId: " + paths[0]);
        // Save appId for future use
        globalService.applicationId = paths[0];
    } else {
        let newAppId = Math.random().toString(36).substr(2, 5);
        // Save appId for future use
        globalService.applicationId = newAppId;
    }

    let basePath = globalService.applicationId;
    console.log("getBaseLocation : /" + basePath);
    return '/' + basePath;
}

It works fine when accessing localhost:4200 which is redirected to localhost:4200/{random-string}/home. However, I received the error in browser console when clicking another link on the page or simply refreshing the current page. Error is like this:

GET http://localhost:4200/iun82/1.chunk.js 404 (Not Found)

ERROR Error: Uncaught (in promise): Error: Loading chunk 1 failed.

Error: Loading chunk 1 failed.

Please advise. Thanks!

Softhinker.com
  • 875
  • 2
  • 11
  • 24

1 Answers1

1

If you need to inject a service to a factory function, use the following syntax:

  providers: [
    appRoutingProviders,
    provide: MyService, 
    {
        provide: APP_BASE_HREF,
        useFactory: getBaseLocation, deps: [MyService]
    },
  ]
Yakov Fain
  • 11,300
  • 4
  • 31
  • 36
  • Thanks Yakov! But I received "Unhandled Promise rejection: url.replace is not a function" when implementing in this way: export function getBaseLocation() { return (svc: MyService): string => { return '/' + randomStr; }} – Softhinker.com May 30 '17 at 00:13
  • 1
    Since you're injecting an object into a function, it has to be declared with an argument, e.g. getBaseLocation(svc: MyService) {...} – Yakov Fain May 30 '17 at 02:18
  • You're right Yakov! And then I encountered different error. Please see my updated post above. – Softhinker.com May 30 '17 at 02:44
  • Your 404 is related to lazy loading. See the console output of ng serve. Your app tries to load 1.chunk.js (one of your lazily-loaded modules), and if you do everything right in your code the ng serve command should build a separate bundle called 1.chunk.js. – Yakov Fain May 30 '17 at 12:35
  • But there is no error output in ng serve. Do I need to do something in app-routing.ts to cater for the customized APP_BASE_HREF? – Softhinker.com May 30 '17 at 20:17