N
N
Nikita Gushchin2014-06-03 01:17:40
JavaScript
Nikita Gushchin, 2014-06-03 01:17:40

AngularJS, config loading before app launch?

Hello! I will briefly describe the situation: there is a project, there is a client, there is a server. The project is developed by different people, everything is synchronized via GIT. The project has a config file that contains URLs for API requests. For normal development, you need two configs - with one ( client.config.json : where all the urls of requests to the server API are replaced with URLs of static JSON files), the front-end developer works, with the other ( server.config.json : where the url is as they should be - real server API url) is being worked by another developer. Well, in order for this whole kitchen to work, there is one common configuration file ( config.json ), which indicates which of the two configs to load the angular application. This was done for normal work with GIT, so that each time you could not change anything and the fileconfig.json do not commit.
There was such a question: I wanted to load configs as a service constant in angular:

var app = angular.module(...)
app.constant('ENV',config);

But I need the config to be loaded before other modules\services\etc. After googling, I decided to make a resolve in the $routeProvider config:
$routeProvider.when('/home', {
            templateUrl: 'partials/home.html',
            controller: 'HomePageCtrl',
            activeTab: 'home',
            resolve: { loadConf: loadEnvironmentConfig }
});

The loadEnvironmentConfig function - loads the config according to the above algorithm:
var loadEnvironmentConfig = function ($http) {
        return $http.get('./config.json').then(function (resData) {
            return $http.get('./'+resData.data.ENV+'.config.json').then(function (configData) {
                var environmentConfig = {
                    NAME: resData.data.ENV,
                    CONFIG: angular.extend({},configData.data)
                };
                app.constant('ENV',environmentConfig); // Тут возникают проблемы
            });
        });
    };

But I ran into one annoying problem: the services start to initialize before this construct works, and the dependency injector throws an error that the ENV module was not found:
app.factory('Image', [ '$resource', 'ENV', function ($resource,ENV) {
        return $resource(ENV.CONFIG.Image.url, {}, {
            query: {method:'GET', params:{phoneId:'all'}, isArray:true}
        });
    }]);

Can this be fixed somehow?
I did this: instead of a constant, I defined ENV as value:
app.value('ENV',{});
And I load it like this:
var loadEnvironmentConfig = function ($http,ENV) {
        return $http.get('./config.json').then(function (resData) {
            return $http.get('./'+resData.data.ENV+'.config.json').then(function (configData) {
                var environmentConfig = {
                    NAME: resData.data.ENV,
                    CONFIG: angular.extend({},configData.data)
                };
                angular.extend(ENV,environmentConfig);
            });
        });
    };

This code runs without errors, but I don't like that ENV is not a constant. Tell me, can I somehow make a variant with a constant? Or maybe there are more adequate ways to load the configuration?
Thanks in advance.

Answer the question

In order to leave comments, you need to log in

2 answer(s)
M
maxaon, 2014-06-08
@iNikNik

The easiest way is not to use the automatic bootstrap of angular:
1. Loading the config (either via XMLHttpRequest or via Jquery)
2. Processing the config, registering the constant.
3. Bootstrap angular.
A simple example jsbin.com/vanoliyo/2/edit
But a better way would be to minimize requests to the server so as not to pause the app's bootstrap and not wait for two consecutive requests. How to do this depends a lot on the environment.

S
Sergey, 2014-06-03
Protko @Fesor

But I need the config to be loaded before other modules\services\etc

Wrong. Angular has lazy module loading. The launch of the application is preceded by a configuration stage, in which all service providers, contacts, etc. will already be launched.
Your problem is that you are loading the config after the configuration stage, you need to configure the collector so that it substitutes the module with the config depending on the environment.
I have a similar system for storing configs - I just made a task to build for a specific environment.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question