1

My apps are using many web services on the intranet, and url-s for those depend on the server environment.

My apps are hosted on IIS, which adds an HTTP response header like this: Environment: DEV, so every web app knows in which server environment it is running, and thus which intranet servers it must use to call all the services.

Each of my angular apps uses a service that issues a simple GET against the app's own root just to get any response with the environment name in it, and set configuration accordingly.

Question:

How should an angular app implement such a service that would execute as the very first thing in the application, and make sure that while it is getting that first response, nothing in the app tries to execute an HTTP request against other services, or even try to use any configuration provided by my environment service?

Is there a way to implement such a service in angular that could block every other service / factory in the application till it is done initializing itself?

I have many other services in the app, and none of them really know what to do till my environment service has finished its initialization.


UPDATE

Looking at it from another angle.... is it possible to implement such an interceptor in angular that could do the following?:

  • execute an HTTP request and block the app's execution till it gets a response
  • make information from the response available throughout the app as a service/factory/config.
vitaly-t
  • 24,279
  • 15
  • 116
  • 138
  • 1
    You'll need to [bootstrap your application configruation](http://stackoverflow.com/questions/22825706/angularjs-load-config-on-app-start). – Jasen Aug 25 '16 at 17:29
  • A router such as `ngRoute` or `ui-router` can use a resolver function to block a view until a promse resolves. – georgeawg Aug 25 '16 at 19:18

1 Answers1

1

Angular lifecycle could be one solution. Using the angular.config() phase you could peek at the headers of the HTTP service.

Create a factory called 'httpInterceptor'

function httpInterceptors(siteConfig, $q, $injector) {
    return {
        response: function(data, status, headers) {
            siteConfig.setEnvironment(headers['Environment']);
            return data;
        }
    };
)

Then in angular.config()

$httpProvider.interceptors.push('httpInterceptor');

If you truly want to block the other option is to use UI router resolve property to block routes loading until the request has been made https://github.com/angular-ui/ui-router/wiki you can add the resolve method to the root state.

Resolve

You can use resolve to provide your controller with content or data that > is custom to the state. resolve is an optional map of dependencies which > should be injected into the controller.

If any of these dependencies are promises, they will be resolved and converted to a value before the controller is instantiated and the $stateChangeSuccess event is fired.

Community
  • 1
  • 1
d3l33t
  • 890
  • 6
  • 10
  • I'm confused about the first approach that you are suggesting, setting HTTP response within the client's code. In my situation only the hosting server sets the environment, not the client. I need the client to peek the response to detect the environment. – vitaly-t Aug 25 '16 at 17:39
  • question, what are you doing with the response header env from the server? – d3l33t Aug 25 '16 at 17:41
  • My app upon start needs to issue a request against its own root to get any response. From the response it reads variable `Environment` within the header, and based on that configures url-s for all the external services it needs to use. It goes without saying, the app needs to do it only once. – vitaly-t Aug 25 '16 at 17:44
  • In that case i would use the second example OR you can configure the provider for your service that would configure the service before its instantiated. You will need to use var $http = $injector.get('$http'); in the provider. check this out to learn more about providers https://docs.angularjs.org/guide/providers – d3l33t Aug 25 '16 at 17:50