0

I have an Angular application that has a circular dependency between 3 different types. I have built an interceptor that uses something called AuthorizationService so that if the user is authorized a bearer token is automatically added as part of a HTTP request. This used to work fine until I wanted my client id and tenant id to be configurable and injected in as part of the environment variables (the application ends up in a Docker container in the end, and the auth implementation uses Azure AD).

In order to compensate for this I updated my existing EnvironmentService to also read the client id and tenant id from a JSON file (which gets overriden on deploy). The implementation of which uses HttpClient to read the file, something like the following, where load() gets called on app initialization:

...
constructor(private http: HttpClient) { }

load(): void {
    this.http.get(configLocation).subscribe(data => {
        ...
        this.clientId = data.clientId;
    });
}
...

And the AuthorizationService was updated to look like the following:

...
constructor(private environmentService: EnvironmentService) {
    this.clientId = environmentService.clientId;
    this.tenantId = environmentService.tenantId;
}

login(): void {
   ... initializes login that uses the variables set above
}
...

This is where the issue now comes in. The AuthorizationService depends on EnvironmentService, which depends on HttpClient which depends on AuthorizationService due to the interceptor for HttpClient. There's no guarantee that I can see for the order in which things are loaded and I can see in the console logs that a maximum number of stacks is reached.

I tried a different tactic instead where instead of reading the JSON file via HttpClient I just loaded it straight into the class instead. This works, except when you want to deploy and you build using the --prod configuration - instead of referencing the JSON file it is optimised to be inline which means environment variables from the other config file are no longer read, and so the values in the JSON file become static to local settings. I couldn't find a way of excluding the JSON file from optimization. To be clear the difference between the two JSON files is like follows:

local config.json

{
    apiUrl: 'http://localhost:80'
    clientId: '123456789',
    tenantId: '987654321'
}

template config.json

{
    apiUrl: '${apiUrl}',
    clientId: '${clientId}',
    tenantId: '${tenantId}'
}

I'm struggling for ideas on what to do next and how to achieve this. I've tried a number of different refactors like the one described above with no success. Has anyone come across a similar issue before, and if so how do you resolve it?

Serberuss
  • 2,247
  • 4
  • 22
  • 40
  • You can check for the login url at the interceptor to prevent infinite recursion, if I understand what´s your issue well – dcg Feb 24 '20 at 21:48
  • Have you read e.g. https://stackoverflow.com/questions/46470469/angular-4-3x-dynamic-http-interceptor? – jonrsharpe Feb 24 '20 at 21:48
  • @dcg OP could exclude the config-address in your interceptor not login. – Nikolaus Feb 24 '20 at 22:19
  • You could try this solution: https://stackoverflow.com/questions/46469349/how-to-make-an-angular-module-to-ignore-http-interceptor-added-in-a-core-module – mbojko Feb 24 '20 at 22:25

0 Answers0