Configure URL from server before http-request in Angular

Posted on August 16, 2017
Diagram of an angular application and a backend application, both on different servers

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.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
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
      this.http.get('/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.