Search code examples
javascriptangularjsangularjs-service

How do I configure different environments in Angular.js?


How do you manage configuration variables/constants for different environments?

This could be an example:

My rest API is reachable on localhost:7080/myapi/, but my friend that works on the same code under Git version control has the API deployed on his Tomcat on localhost:8099/hisapi/.

Supposing that we have something like this :

angular
    .module('app', ['ngResource'])

    .constant('API_END_POINT','<local_end_point>')

    .factory('User', function($resource, API_END_POINT) {
        return $resource(API_END_POINT + 'user');
    });

How do I dynamically inject the correct value of the API endpoint, depending on the environment?

In PHP I usually do this kind of stuff with a config.username.xml file, merging the basic configuration file (config.xml) with the local environment configuration file recognised by the name of the user. But I don't know how to manage this kind of thing in JavaScript?


Solution

  • I'm a little late to the thread, but if you're using Grunt I've had great success with grunt-ng-constant.

    The config section for ngconstant in my Gruntfile.js looks like

    ngconstant: {
      options: {
        name: 'config',
        wrap: '"use strict";\n\n{%= __ngModule %}',
        space: '  '
      },
      development: {
        options: {
          dest: '<%= yeoman.app %>/scripts/config.js'
        },
        constants: {
          ENV: 'development'
        }
      },
      production: {
        options: {
          dest: '<%= yeoman.dist %>/scripts/config.js'
        },
        constants: {
          ENV: 'production'
        }
      }
    }
    

    The tasks that use ngconstant look like

    grunt.registerTask('server', function (target) {
      if (target === 'dist') {
        return grunt.task.run([
          'build',
          'open',
          'connect:dist:keepalive'
        ]);
      }
    
      grunt.task.run([
        'clean:server',
        'ngconstant:development',
        'concurrent:server',
        'connect:livereload',
        'open',
        'watch'
      ]);
    });
    
    grunt.registerTask('build', [
      'clean:dist',
      'ngconstant:production',
      'useminPrepare',
      'concurrent:dist',
      'concat',
      'copy',
      'cdnify',
      'ngmin',
      'cssmin',
      'uglify',
      'rev',
      'usemin'
    ]);
    

    So running grunt server will generate a config.js file in app/scripts/ that looks like

    "use strict";
    angular.module("config", []).constant("ENV", "development");
    

    Finally, I declare the dependency on whatever modules need it:

    // the 'config' dependency is generated via grunt
    var app = angular.module('myApp', [ 'config' ]);
    

    Now my constants can be dependency injected where needed. E.g.,

    app.controller('MyController', ['ENV', function( ENV ) {
      if( ENV === 'production' ) {
        ...
      }
    }]);