Saqib Ali
Saqib Ali

Reputation: 12585

How to make an angular application take arguments from command line?

I have an AngularJS application in which my code looks something like this:

myApp = angular.module('myApp',
  [
    'ui.router',
    'ngMaterial',
    'ngMessages'
  ]
);

myApp.constant('CONSTANTS', (function() {
  // Define your variable
  return {
    backend: {
      baseURL: 'http://mybackend.com:3026'
    }
  };
})());

I run this application using http-server on port number 8000 like this:

% http-server -p 8000

I want to pass in a command-line argument for the backend.baseURL such that it over-rides the value specified in the code. How can I do it??

Upvotes: 18

Views: 7558

Answers (5)

Yury Glushkov
Yury Glushkov

Reputation: 750

If you use only one instance of your app, you can start it with script, that accepts all necessary command line arguments, replaces appropriate placeholders (string between specific comments, for example) in your application js files and then launches http-server on necessary port.

Upvotes: 1

Pankaj Badukale
Pankaj Badukale

Reputation: 2044

Basically what I understand is that you want to customize http-server package for your won custom handling.

Here is small solution I found for you....

Go to node installation folder(In my case its local one)...

So path of file which we going to edit is like this...

../node_modules/http-server/lib/http-server.js

Import one package which serve you to get command line arguments...you don't need to install it, its already there.

var argv = require('optimist').boolean('cors').argv; // add this line at top after line number 7

Now

At line 60 and after code before.push(function (req, res) { add following code..

if( req.url === '/backend-url' ) {
  return res.end(JSON.stringify(argv.x));
}

So before push function will look like::

  before.push(function (req, res) {
    if( req.url === '/backend-url' ) {
      return res.end(JSON.stringify(argv.x));
    }
    if (options.logFn) {
      options.logFn(req, res);
    }

    res.emit('next');
  });

now we have configured our new command line argument x for http-server which will be return for url "/backend-url"

Now at front end

myApp.constant('CONSTANTS', ('$http', function($http) {
// Define your variable
**var backendURL = (function() {
    return $http.get('/backend-url', function(bUrl) {
        return bUrl;
    })
})();**
return {
    backend: {
        baseURL: backendURL
    }
};
})());

Done, now you add url like this: **http-server -p 8080 -x http://example.com**

I choose this approch as replacing file content i dont think good in you case 

Upvotes: 1

Gurpreet
Gurpreet

Reputation: 1442

looks like you are not using gulp but you are using node script from package.json. if you are using gulp then this should not be a problem you you use http-server via gulp. one thing you can do in your current case is as part of your run command, set process.env.baseUrl="dynamic" and then roughly speaking, use this in your code like this

return {
backend: {
  baseURL:process.env.baseUrl || 'http://fallbackurl'
}

Upvotes: 1

Tim Marsh
Tim Marsh

Reputation: 276

when Ive done this in production I use the build process for this, using gulp in this case,

  var knownOptions = {
    string: 'env',
    default: { env: process.env.NODE_ENV || 'default' }
  };

  var options = minimist(process.argv.slice(2), knownOptions);

  console.log("using config : " + chalk.blue(options.env));

we get an environment variable defaulting to default using minimist we can pass -env 'string'

then further in the code pushing a dynamic file onto app.js

  //now we use options.env
  appJS.push("env/"+options.env+".js");

env/[options.env].js here is an angular module that exports environment specific constants

Upvotes: 1

Hereblur
Hereblur

Reputation: 2164

What you need is at least required http-server that supported dynamic content. while your http-server is supported only static content.

And in the comment you asking which server should you use. There are thousands of web-server that support dynamic content out there. but sinc you are currently using http-server I assumed you just want a small server for local-dev.

Unfortunately, I cannot find any server that support your need without modifying their code. So I suggest you to create your own server base on a library on npm.

This is and example server using live-server.

var liveServer = require("live-server");
var fs = require("fs")

var root = process.argv[2] || "."
var port = process.argv[3] || 8000

var replaceTextMiddleWare = function(req, res, next){

    var file = process.argv[4]
    var find = process.argv[5]
    var replace = process.argv[6]

    if(file && find){
        if(req.url === file) {
                fs.readFile( root + file, "utf-8", function(e, content){
                    res.end( content.replace(find, replace))
                } )

                return;
        }
    }


    next();
}

var params = {
    port: port, // Set the server port. Defaults to 8080.
    host: "0.0.0.0", // Set the address to bind to. Defaults to 0.0.0.0 or process.env.IP.
    root: root, // Set root directory that's being server. Defaults to cwd.
    open: false, // When false, it won't load your browser by default.
    ignore: 'scss,my/templates', // comma-separated string for paths to ignore
    file: "index.html", // When set, serve this file for every 404 (useful for single-page applications)
    wait: 1000, // Waits for all changes, before reloading. Defaults to 0 sec.
    mount: [['/components', './node_modules']], // Mount a directory to a route.
    logLevel: 2, // 0 = errors only, 1 = some, 2 = lots
    middleware: [ replaceTextMiddleWare ] // Takes an array of Connect-compatible middleware that are injected into the server middleware stack
};


liveServer.start(params);

Then you can run your server by

nodejs myserver.js /mydocument/myproject/ 8000 config.js "http://mybackend.com:3026" "http://mydevserver.com:80"

The command accept parameters:

  • Path to serve content
  • Port
  • File name
  • Text to find
  • Text to replace

This server support only one dynamic file with simple find/replace. From this point, I guess you can modify middleware to do whatever you want.

Upvotes: 3

Related Questions