5

I have an app, and a library, two separate repos. My app consumes my library, and my library contains a service which performs a http request.

My app deploys to several environments and I use Angular's environment.ts file to define where the external services live. All apps are served via a gateway and live on the same window.location.origin.

ivy is disabled and aot is enabled.

My Library exposes a forRoot as follows:

  declarations: [
    ToggleDirective
  ],
  providers: [
    ToggleService,
    ToggleServiceConfig
  ],
  exports: [
    ToggleDirective
  ]
})
export class ToggleModule {
  static forRoot(config: ToggleServiceConfig): ModuleWithProviders<ToggleModule> {
    return {
      ngModule: ToggleModule,
      providers: [
        {provide: ToggleServiceConfig, useValue: config }
      ]
    };
  }
}

My App's environment.ts looks like this:

export const environment = {
   ...
   togglesUrl: window.location.origin + '/release-toggling',
   ...
};

In my App's app.module, I configure it like this:


...

const releaseToggleServiceConfig: ToggleServiceConfig = {
    togglesUrl: environment.togglesUrl
};

...

@NgModule({
    declarations: [AppComponent],
    imports: [
        CoreModule,
        SharedModule,
        ...
        ToggleModule.forRoot(releaseToggleServiceConfig)
    ],
    ...
})
export class AppModule {}

if I hard code the window.location.origin (locally, to 'localhost:4200') then it works fine. Obviously, the window doesn't exist at this stage yet. It may be something to do with aot but disabling aot is not an option here unfortunately.

What's the best pattern/practice here to pass the window.location.origin properly. technically, it's not needed until the app does the call to my external service.

I'm interested in your solutions or suggestions. This may be something simple to solve, that many have faced before.

ldusoswa
  • 51
  • 3
  • just for debugging and confirming that the window.location.origin is acturally null at this point. in your `forRoot` function, can you `console.log(window.location.origin)` and `console.log(config.togglesUrl)` – Modar Na Mar 25 '21 at 12:31

3 Answers3

0

All apps are served via a gateway and live on the same window.location.origin.

If both apps are living on the same gateway and if the domain is also the same then maybe you can skip window.location.origin in your environment.ts:

export const environment = {
   ...
   togglesUrl: '/release-toggling',
   ...
};
catcher
  • 101
  • 1
  • 5
  • That wont work though because if i'm at http://www.example.com/deep/in/my/app it will try to do it relatively whereas window.location.origin would give me the gateway url (http://www.example.com) – ldusoswa Mar 18 '21 at 15:55
0

Apparently the problem is that the value is resolved during compile time. You might try to use a function instead like togglesUrl: () => window.location.origin and then call it from the code.

Personally I don't see any reason why you would need to use this approach. This gives you no benefit. If you called your service directly with something like my/request this would automatically resolve to the current domain.

Another option is to resolve the origin directly in the services, or a better approach is to create an HttpInterceptor which would patch the request URL at run time.

P.S. You know the URL in advance, so you could easily define correct URL at the very beginning and not play with Location.

Sergey
  • 7,184
  • 13
  • 42
  • 85
0

I think you need to use something else than storing the domain in your environments.

Some options:

  1. Use relative URLs Eg: this.http.get('/someUrl') In this case the request is made to the current domain.
  2. Use a proxy for local use. Docs
  3. Use a static URL in your env
  4. Use location.prepareExternalUrl docs
  5. probably a combination
Robin Dijkhof
  • 18,665
  • 11
  • 65
  • 116