9

I am trying to read environment variables in http get calls

$http.get('http://'  + $location.host() + ':8080/api')

I want to be able to read the environmen variable and use it as the http rest server in teh above API call, as follows

 $http.get('environmental_variable ':8080/api')

Note: I dont know the environment variable until runtime So I cannot have the value before hand to use it as a constant

1
  • 1
    "I want the api address to be an environmental variable". Explain this better. Commented Oct 30, 2015 at 20:22

3 Answers 3

7

There are lots of examples showing how you can put your settings into different files or constants. Most of these work, but miss the point.

Your configuration settings are not part of your code!

Apart from the 'Hello World' examples, your deployment should be carried out by a CI/CD server and this should be responsible for setting your configuration settings. This has a number of benefits:

1) You are deploying the same code to different environments. If you deploy code to a test environment, then you want to deploy the same code to your production environment. If your servers have to rebuild the code, to add the production configuration settings, you are deploying different code.

2) Code can be shared without giving away your API details, AWS settings and other secret information.

3) It allows new environments to be added easily.

There are lots of examples out there on how to do this. One example is www.jvandemo.com/how-to-configure-your-angularjs-application-using-environment-variables

Sign up to request clarification or add additional context in comments.

Comments

4

There are no such things as environment variables in the browser.

The $location service is always going to get your current URL. I guess your API might live on a different host.

It's possible to simulate environment variables by storing configuration in an Angular constant.

app.constant('env', {
  API_URL: "http://someurl.com:8080/api"
});

Then you can inject this constant into your other providers.

app.controller('MyController', function($http, env) {  
  $http.get(env.API_URL);
});

Here's a decent article on best practices with constants. The article favours not using constants, as it's useful to be able to modify the configuration without having to rebuild the code.

The way I normally handle this is to move all the instance configuration details out to a config.json file, then load it with $http when I bootstrap my application.

For instance, you might have a config file like this.

{
  apiUrl: "http://someurl.com:8080/api"
}

Then an Angular service that loads it.

app.service('Config', function($http) {
  return function() {
    return $http.get('config.json');
  };
});

Then other services can get hold of the promise, that will expose the config when resolved.

app.controller('MyController', function($http, Config) {
  Config()
    .then(function(config) {
      $http.get(config.apiUrl);
    });
});

8 Comments

can angular constant be something like 'process.env.ENV_VARIABLE'?
You could name it like that, but it wouldn't use your system's environment variables, as you can't get hold of them through the browser.
If you are prepared to look at React or Angular 2, they both support server side rendering with Node.js. And with Node, you can get hold of environment variables, to template into your code.
what if I dont know the env variable until runtime?
Then you'll have to keep it as part of the client side code, or as a dynamically loaded config file.
|
-2

I strongly suggest you to use a library for setting environment variables. You can use angular-environment plugin to do that: https://www.npmjs.com/package/angular-environment

Here's a example

angular.module('yourApp', ['environment']).
config(function(envServiceProvider) {
    // set the domains and variables for each environment 
    envServiceProvider.config({
        domains: {
            development: ['localhost', 'acme.dev.local'],
            production: ['acme.com', '*.acme.com', 'acme.dev.prod'],
            test: ['test.acme.com', 'acme.dev.test', 'acme.*.com'],
            // anotherStage: ['domain1', 'domain2'] 
        },
        vars: {
            development: {
                apiUrl: '//api.acme.dev.local/v1',
                staticUrl: '//static.acme.dev.local',
                // antoherCustomVar: 'lorem', 
                // antoherCustomVar: 'ipsum' 
            },
            test: {
                apiUrl: '//api.acme.dev.test/v1',
                staticUrl: '//static.acme.dev.test',
                // antoherCustomVar: 'lorem', 
                // antoherCustomVar: 'ipsum' 
            },
            production: {
                apiUrl: '//api.acme.com/v1',
                staticUrl: '//static.acme.com',
                // antoherCustomVar: 'lorem', 
                // antoherCustomVar: 'ipsum' 
            },
            // anotherStage: { 
            //  customVar: 'lorem', 
            //  customVar: 'ipsum' 
            // }, 
            defaults: {
                apiUrl: '//api.default.com/v1',
                staticUrl: '//static.default.com'
            }
        }
    });

    // run the environment check, so the comprobation is made 
    // before controllers and services are built 
    envServiceProvider.check();
});

Then you can get the right variable based on what environment your application is running: var apiUrl = envService.read('apiUrl');

Cheers!

1 Comment

This hard-codes ll of your environment variables into a file that everyone can see. This is the example shown, but it should not be used in a production environment. The settings to be used should be updated by your CI/CD server.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.