Is there any way to inject the JavaScript stored as a string in AngularJS controllers dynamically?

var dynamicJS = "function DoSomething(value){var x = 1+1  return 2;}"

I have to dynamically inject the above function into my AngularJS controller and have it be called on selection change of drop-down, the values of which are bound to the AngularJS controller. The reason is the JavaScript function would vary based on my each row of data which I have based on my configuration at an application level. I am aware we can make use of $eval but would like to get some better approaches, if any exist.

Can anyone give me any idea on this?

Note: I am using AngularJS v1.4.5

share|improve this question
    
Why are you storing a function as a string in the first place? – AJ Funk 6 hours ago
    
    
Per my requirement I have to do some data population or some validations based on the data which I have. In some case I dont need to execute any but for some other case I may need to execute it with the configured JS functions for that data. the JS function is not consistent and I can execute it based on configured for the specific data per my requirement. make sense ?. – Sasi 6 hours ago
    
This is a very dangerous thing to do; it is extremely easy to create attack vectors into your app by modifying these strings. – Claies 6 hours ago
    
it is intranet application and not going to outer world. no issues on this for this req. thank you though. – Sasi 5 hours ago

There are multiple ways to achieve this.

  • Function object

    Create a Function and set the body:

    var dynamicJS = "var x = 1+1;  return 2;"
    var DoSomething = new Function("value", dynamicJS );
    
  • eval()

    While arguably more dangerous1, eval() can be used.

    var dynamicJS = "function DoSomething(value){var x = 1+1  return 2;}"\
    eval(dynamicJS);
    

    Because you mentioned in a comment "it is intranet application and not going to outer world. no issues on this for this req.", this would likely be fine but please read the section below.

    Caution

    From the this section of the MDN documentation about eval():

    Don't use eval needlessly!

    eval() is a dangerous function, which executes the code it's passed with the privileges of the caller. If you run eval() with a string that could be affected by a malicious party, you may end up running malicious code on the user's machine with the permissions of your webpage / extension. More importantly, third party code can see the scope in which eval() was invoked, which can lead to possible attacks in ways to which the similar Function is not susceptible.

    eval() is also generally slower than the alternatives, since it has to invoke the JS interpreter, while many other constructs are optimized by modern JS engines.

    There are safer (and faster!) alternatives to eval() for common use-cases. 2

See a demonstration of these methods utilized below.

var dynamicJS = "function DoSomething(value){var x = 1+1;  return 2;}"
var functionBody = "var x = 1+1;  return 2;";
document.addEventListener('DOMContentLoaded', function() {
  document.getElementById('eval').addEventListener('click', function() {
    eval(dynamicJS);
    console.log('DoSomething(3) -> ',DoSomething(3));
  });
  document.getElementById('function').addEventListener('click', function() {
    var dynamicFunction = new Function("value", functionBody);
    console.log('dynamic function(3) ->',dynamicFunction(3));
  });
});
<button id="eval">click to eval</button>
<button id="function">click to use Function</button>


1http://stackoverflow.com/a/4599946/1575353

2https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval#Don't_use_eval_needlessly!

share|improve this answer
1  
Eval can be very Evil! Take care. developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…! – mr.void 6 hours ago
1  
Yep - agreed. I have incorporated that info. – Sam Onela 6 hours ago

I would believe the easier way will be to parse the String and then use the function constructor.

Something like this:

var DoSomething = new Function('value', 'var x = 1+1  return 2');
share|improve this answer

Perhaps try something like:

function myFunc(obj){
    var param = obj.hasOwnProperty('param') ? obj.param : undefined;
    console.log(param);
}

var funcString = "myFunc({ param: 'something' });",
    Construct = new Function(funcString);

Construct();

Haven't tested it to be honest ... but this way you avoid eval().

more info on Function object

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.