3

I have a JSON object, like this:

var JSON = 
[
  {
    "cat_function":"(function(){console.log('ITS HAPPENING');})();"
  }
]

JSON[0].cat_function;

From my script, I need to load in the function and execute it. Simply calling JSON[0].cat_function doesn't work, which I kinda expected; what's the best way to get this to run?

To clarify, this JSON data is coming from a CSV and the function is obviously more complex than just a console.log. The function is stored as a string and there's not much that can be done about it.

Any ideas?

JVG
  • 20,198
  • 47
  • 132
  • 210
  • does the function accept arguments and/or reference external variables? – georg Jun 18 '13 at 09:24
  • It uses `jQuery` (well, `node.js Cheerio`, but close enough) as well as `node.js Request` to parse a webpage and return some values. It's a self-executing function that doesn't accept any arguments. – JVG Jun 18 '13 at 09:27
  • 1
    This could help: [http://stackoverflow.com/questions/3946958/pass-function-in-json-and-execute](http://stackoverflow.com/questions/3946958/pass-function-in-json-and-execute) – OzrenTkalcecKrznaric Jun 18 '13 at 09:27
  • @Jascination just to be sure, is the `JSON` used in the browser or in `node.js`? – t.niese Jun 18 '13 at 10:44
  • @t.niese it's being imported into `Node.js`, this is a backend script and doesn't use the browser at all. – JVG Jun 18 '13 at 10:56

2 Answers2

2

you could do

var functionCode = JSON[0].cat_function;

var value = eval( functionCode );

Anyway, I should warn you that eval is evil so if you can implement another way to import the code it will be better.

Edorka
  • 1,781
  • 12
  • 24
  • Why evil? This is happening in a `node.js` script, not in the browser if that makes any difference. Not really any other way to load in the code unfortunately! – JVG Jun 18 '13 at 09:24
  • Another ones explained it better than me: http://jslinterrors.com/eval-is-evil/ I only wanted to encourage you to use another solution if it were available but in this case I suppose your options are limited. – Edorka Jun 18 '13 at 09:29
  • 2
    @Edorka the `eval` is `evil` is always a little bit misleading, it is not wrong, but it sound always that just `eval` is bad. If you load scripts from external sites (e.g. from `cdn` or via `jsonp` or if it is a node project from a repos) or using `new Function`/`eval` you always have similar issues. Mainly: you need to trust the source because it can execute some code on your page. – t.niese Jun 18 '13 at 10:04
  • Right said @t.niese, but eval() is one of my try-to-avoid options more because of readability than for security reasons. I was however not talking about nodejs, I've not any experience with it. – Edorka Jun 18 '13 at 10:13
  • @t.niese Very interesting. The code source is coming directly from me (CSV converted to JSON) so I suppose it should be ok? – JVG Jun 18 '13 at 10:19
  • @Edorka Exactly. In nearly every case you can avoid `eval`. I don't use it because it would break on the one hand my code optimization and on the other hand it breaks the _quality layer_ that i have when i use `jslint` or `jshint`. – t.niese Jun 18 '13 at 10:52
1

This is more a comment/pseudo-code because i currently don't use node.js often (so i could be wrong about it).

But what about doing it in a similar way how jsonp works in the browser:

The response you create (loaded data)

handleResponse({
    status : 200,  /* some statuscode like 200, 400 if required */
    data : {
         cat_function : function(){
                            console.log('ITS HAPPENING');
                        },
        some_data : 12345
    }
});

The function that handles the response (in your application code)

 function handleResponse( response ) {
    response.data.cat_function();
 }

The part where you load and execute it (in your application code)

 vm = require('vm');
 yourResponse = functionToLoadTheResponse();
 vm.runInThisContext(yourResponse);
t.niese
  • 39,256
  • 9
  • 74
  • 101
  • `handleResponse()` is a bit beyond my javascript knowledge, are we talking about an in-browser response? – JVG Jun 18 '13 at 11:49