6

I have 3 of AngularJS apps on Heroku. Each of them consumes different API.

(For example: angularjs-dev consume api-dev, angularjs-qa consumes api-qa)

I created constant file like this below

SITE     = 'dev'
API_SITE = {
      dev       : 'dev-url',
      qa        : 'qa-url',
      production: 'production-url'
}

And then when I want the API url, I call it this way API_SITE[SITE]

This problem is when I want to deploy to qa, I have to change SITE to qa.

I wonder that: can we make AngularJS read environment variables defined on Heroku so we won't have to change it manually again

Note: I know that AngularJS is running on client-side. So, I have no idea how to do it.

Anyone?

3 Answers 3

11

In case that someone is looking for the solution (based on my environment: AngularJS and NodeJS on Heroku)

I added this code to web.js (NodeJS starter file)

var options = {};
var jade = require('jade');

app.get('/site.js', function(req, res){
    res.send("var SITE='"+process.env.SITE+"'");
});

Then, in file index.html I just added <script src="/site.js"></script> for retriving SITE variable.

It works well.

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

4 Comments

Nice little hack. the res.send() part looks weird with all the concatenation but it worked! :)
I always get SITE=undefined. Should I set manually process.env.SITE ?
@ste You should set it manually first to see if if works, and then change it to process.env.SITE
Yes, done like you said and it works perfectly :) Thanks a lot
2

Since this question asked how to access variables plural and for my own use case I had more than one config var for use in the client I wanted to share a way to send vars from heroku to the client with one get request. It's similar to @BunSuwanparsert answer but instead of using res.send() I used res.write()

//server.js

app.get('/config.js', function(req, res){

   res.write("var SOME_URL='"+process.env.SOME_URL+"'" + '\n');
   res.write("var API_KEY='"+process.env.API_KEY+"'" + '\n');
   res.write("var AUTH_DOM='"+process.env.AUTH_DOM+"'" + '\n');
   res.write("var STRG_BUCKET='"+process.env.STRG_BUCKET+"'" + '\n');
   res.write("var MSG_SND_ID='"+process.env.MSG_SND_ID+"'" + '\n');
   res.end();

});

 
  <script src="/config.js"></script>
and then add the script in index.html

Comments

1

This can be done if you are using webpack for bundling your client app, by using the DefinePlugin that allows you to create global constants which can be configured at compile time.

To achieve this, add something like the following to your webpack.config.js:

var constants = {
     'webpack.constants.envVar1' : process.env.HEROKU_ENV_VAR_1,
     'webpack.constants.envVar2' : process.env.HEROKU_ENV_VAR_2,
     ...
};

module.exports = {
    ...
    plugins: [new webpack.DefinePlugin(constants),..],
    ...
};

You can then reference your Heroku env vars anywhere in your AngularJS client app, e.g.

doSomething(webpack.constants.envVar1);

However, the fact that this CAN be done does not necessarily mean that this SHOULD be done, at least not on Heroku. The reason it might not be a great idea to do this on Heroku is that this scheme doesn't play nicely with Heroku Pipelines.

Webpack needs to run as part of the Heroku slug compilation, e.g. in an npm postinstall script.

Now, if you have a Heroku Pipeline with, say, development, staging and production apps, and your deployment workflow is to git push to the development app, and then to promote the slug to your staging and subsequently to your production apps, then BE AWARE that the slug ONLY gets built when you git push to your development app. It is NOT subsequently rebuilt when promoted up the pipeline. This means that webpack ONLY runs once, and if you employ the scheme described above for using env vars in your AngularJS app, the AngularJS client of your staging and production apps will end up using the Heroku env var values you assigned to your development app, which might NOT be what you intended!!

3 Comments

I actually had to do a little bit more to get my env vars into my angular client from webpack.config. const constants = { 'API_KEY': JSON.stringify(process.env.API_KEY) } I had to wrap the process.env.API_KEY in JSON.stringify(). and I had to [ plugins: new webpack.DefinePlugin({ 'process.env': constants }) ] wrap the constants object with an object and attribute of 'process.env' then in the client I could get the env vars like this const config = { apiKey: process.env.API_KEY }
So do you know how to get this to work for Heroku Pipelines?
One way to do this with Heroku Pipeline apps is to simply send a request to the server for any env vars when your angular app initializes. That way, the env var values returned to the client can be different per Heroku pipeline app. That is basically what @BunSuwanparsert suggested.

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.