Call function from string in nodejs

Write your functions in a separate file and export them and use with name reference of that to call them, Like

//    functions.js
var funcOne = function(){
                   console.log('function ONE called')
              }
module.exports={
    //  name_exported : internal_name
    funcOne : funcOne
}

Use function defined in functions.js in index.js :

//    index.js
var methods = require('./functions.js')   // path to functions.js
methods['funcOne']()

OUTPUT :

> node index.js
> function ONE called

It works just fine

global.foo = function foo () {
  console.log("foo was called");
}

process.stdin.on("data", function(input) {

  // don't forget to call .trim() to remove the \n
  var fn = input.toString().trim();

  // function exists
  if (fn in global && typeof global[fn] === "function") {
    global[fn]();
  }

  // function does not exist
  else {
    console.log("could not find " + fn + " function");
  }
});

process.stdin.resume();

Output

foo
foo was called
bar
could not find bar function

Whether or not this is a good idea... well, that's an entirely different discussion.


EDIT — ≈18 months later... Yeah, it's a horrible idea to call a global function like that.

In saying that, here's one way you could approach the problem in a much better way. Below we're going to build a little REPL (read-eval-print loop). In order to understand it better, I'll break it down into a couple parts.

First, we want to make sure our REPL waits for the user to press enter before we try running their command. To do that, we'll create a transform stream that waits for a "\n" character before sending a line down the pipe

The code below is written using ES6. If you're having trouble finding a compatible environment to run the code, I suggest you check out babel.

// line-unitizer.js
import {Transform} from 'stream';

class LineUnitizer extends Transform {
  constructor(delimiter="\n") {
    super();
    this.buffer = "";
    this.delimiter = delimiter;
  }
  _transform(chunk, enc, done) {
    this.buffer += chunk.toString();
    var lines = this.buffer.split(this.delimiter);
    this.buffer = lines.pop();
    lines.forEach(line => this.push(line));
    done();
  }
}

export default LineUnitizer;

Don't get too hung up on LineUnitizer if you're new to stream processing and it doesn't quite make sense. This kind of stream transform is extremely common. The general idea is this: once we pipe process.stdin into a receiving stream, process.stdin will be emitting data every time the user presses a key. However, our Repl (implemented below) can't act on a command until the user has finished typing the command. LineUnitizer is the part that waits for the user to press enter (which inserts a "\n" into the stream) and then signals to _transform that the command is ready to be sent to repl for processing!

Let's look at Repl now

// repl.js
import {Writable} from 'stream';

class Repl extends Writable {
  _parse(line) {
    var [cmd, ...args] = line.split(/\s+/);
    return {cmd, args};
  }
  _write(line, enc, done) {
    var {cmd, args} = this._parse(line.toString());
    this.emit(cmd, args);
    done();
  }
}

export default Repl;

Well hey, that was easy! What does it do tho? Each time repl receives a line, it emits an event with some args. Here's a visual way to see how a command is parsed

The user enters       emit event      args
-------------------------------------------------------------
add 1 2 3             "add"           ["1", "2", "3"]
hens chocobo cucco    "hens"          ["chocobo", "cucco"]
yay                   "yay"           []

Ok, now let's wire everything together to see it work

// start.js
import LineUnitizer from './line-unitizer';
import Repl         from './repl';

process.stdin
  .pipe(new LineUnitizer())
  .pipe(
    (new Repl())
      .on("add", function(args) {
        var sum = args.map(Number).reduce((a,b) => a+b, 0);
        console.log("add result: %d", sum);
      })
      .on("shout", function(args) {
        var allcaps = args.map(s => s.toUpperCase()).join(" ");
        console.log(allcaps);
      })
      .on("exit", function(args) {
        console.log("kthxbai!");
        process.exit();
      }));

Run it

$ node start.js

Output

Lines prefixed with > are user input. The > will not actually be visible in your terminal.

> add 1 2 3
add result: 6
> shout I can see it in your face!
I CAN SEE IT IN YOUR FACE!
> exit
kthxbai!

If you think that's awesome, we're not even done yet. The benefits of writing our program this way is that we can act on the commands regardless of how they arrive at our program.

Consider this commands.txt file

add 100 200
shout streams are the bee's knees
exit

Now run it like this

$ cat commands.txt | node start.js

Output

300
STREAMS ARE THE BEE'S KNEES
kthxbai!

Ok, so that's pretty fricken great. Now consider that the commands could come from anywhere. Could be a database event, something across the network, a CRON job, etc. Because everything is nicely separated, we could easily adapt this program to accept a variety of inputs with ease.