Configure URL from server before http-request in Angular

Configure URL from server before http-request in Angular

For an angular application which is deployed inhouse to several customers,
the application has to figure out, where the backend server exists.

Setting the url in the environment was not useful, as each customer needs
his own url and this would end up in big build scripts.

Also the customer could not reorganize the server names on his own, without
breaking the application if he chooses to change the server name.

So we tried to be clever and to figure out where the server might be in
loading a configuration file from an untouched json file in the application.

find json file with url in application diagram

Or if there is no such file, try to test if the angular app and the backend are
on the same server and use that value as base url.

find backend on same server diagram

First we had this in the init method of the app component. This worked well
on our developer machines, but not on slow internet connections, as we did
our first http calls to the backend before the result with the correct url
was returned.

ngOnInit(): void {
  // this method returns http://<host>:<port>/<baseurl>/config.json
  const hostWithBaseUrl = this.location.prepareExternalUrl('config.json');
  this.http.get(hostWithBaseUrl).map(resp => resp.json())
    .subscribe(config => {
      environment['backendUrl'] = config.backendUrl;
    err => {
      // fallback, try same host
      // this method uses http://<host>:<port>/backend/index.html
       .subscribe(resp => { 
         environment['backendUrl'] = '/backend/rest'; 

We fixed this issue with having a cached url which is put into an observable,
if exist, otherwise an observable fetching the right url is called first,
before any http call to the backend is made.

This plunker should simulate an http call which has to wait until a url is found
and after that, all other clicks to the button use the cached url.

This solution also works, if you hit the button before the url was found. Then
the find url process is used for that http call as well.