Leveraging the power of AngularJS to run JavaScript functions saved as strings

Is it possible to dynamically inject JavaScript code that is stored in a string into AngularJS controllers?

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

I need to inject the above function dynamically into my AngularJS controller and have it executed when there is a selection change in a drop-down menu. The values in the drop-down are bound to the AngularJS controller. Each row of data may require a different JavaScript function, which is determined by application configuration. While I am aware of using $eval, I am looking for better approaches if they exist.

Does anyone have any suggestions or ideas on how to achieve this?

Note: Using AngularJS v1.4.5

Answer №1

There are various methods to accomplish this task.

  • Using a Function Object

    To achieve this, you can create a Function by passing the necessary argument (such as value) and defining the functionBody:

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

    Another approach is to use eval(), although it is considered risky:

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

    If your application is internal and isolated from external influences, this method may suffice. However, caution is advised, as highlighted below.

    Be Cautious

    The MDN documentation regarding eval() emphasizes the risks associated with its usage:

    Avoid Unnecessary eval() Calls

    eval() is a powerful yet dangerous feature that executes code within the caller's context. If the input supplied to eval() is tampered with malicious intent, it could lead to execution of harmful code on the user's device with the permissions granted to your application or extension. Additionally, third-party scripts can access the scope in which eval() was invoked, potentially enabling security vulnerabilities not present when using a similar approach with Function.

    eval() also tends to be slower compared to alternative techniques, as it requires invoking the JavaScript interpreter every time, unlike other optimized constructs supported by modern JavaScript engines.

    For most common scenarios, there exist safer and more efficient alternatives to eval(). 2

Below, you'll find a demonstration showcasing these methodologies in action. Click on the respective buttons to observe their output in the console.

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>


1

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

Answer №2

It seems like the most straightforward approach would involve parsing the String and utilizing the function constructor.

One possible implementation could look something like this:

var PerformAction = new Function('input', 'let result = input * 2; return result;');

Answer №3

Why not give this a shot:

function customFunc(data){
    var info = data.hasOwnProperty('info') ? data.info : undefined;
    console.log(info);
}

var functionInput = "customFunc({ info: 'example' });",
    Generator = new Function(functionInput);

Generator();

I haven't actually tested it myself... but using this method can help you avoid utilizing eval().

For more details, check out the Function object documentation.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Bindings with Angular.js

I have developed an application similar to Pastebin. My goal is to allow users to paste code snippets and display them with syntax highlighting and other visual enhancements, regardless of the programming language used. To achieve this, I utilize Google&ap ...

Sending data from events to a textbox and a div

I've set an onClick event for a textbox. Is there a way to have the click event of a different div also execute when clicking on the textbox, even though they are not nested and in separate parts of the document? Any help with this in Javascript would ...

Incorporate personalized buttons into the header navigation for each view using VueJS

In my VueJS project, I attempted to include custom buttons in the sub navigation menu which could be customized for each view. Initially, I tried adding a simple property to the main data element, but that didn't yield the desired results. Then, I cam ...

Transforming two child arrays within an object into a single array using Ramda

I am looking to transform an object into an array. The object I have is structured like this: const data = { t1: [ {"a": 1, "a1": 2}, {"b": 3, "b1": 4}, {"c": 5, "c1": 6} ], t2: [ {" ...

Having trouble serving static files with express.Router?

With my file system becoming more complex, I decided to switch from using app.use(express.static()) to utilizing express.Router(). Initially, I thought I could just replace app.use(express.static()) with router.use(express.static()), but unfortunately, thi ...

The issue with the NextJS Layout component is that it is failing to display the page content, with an error message indicating that objects cannot be used

I am embarking on my first project using Next JS and after watching several tutorial videos, I find the Layout component to be a perfect fit for my project! However, I am encountering an issue where the page content does not display. The Menu and Footer a ...

Mistakenly appearing at the top of the window instead of the bottom of the window

Utilizing Vue.js to fetch resources from a Laravel API periodically and paginate(), after retrieving the initial 10 instances, I aim to get the next 10. Here's how my method looks: scroll () { window.onscroll = () => { let bottomOf ...

Avoid activating the panel by pressing the button on the expansion header

I'm facing a problem with the delete button on my expansion panel. Instead of just triggering a dialogue, clicking on the delete button also expands the panel. How can I prevent this from happening? https://i.stack.imgur.com/cc4G0.gif <v-expansion ...

Modifying the value property of the parent element

Here is an example of the HTML code I am working with: <td value='3' style='text-align: center'> <select class='selection' onchange=''> <option value='1'>1</option> <opti ...

Create a new storefront JavaScript plugin for Shopware 6 to replace the existing one

I am attempting to replace an existing JavaScript plugin in Shopware 6. However, the code within the plugin file does not seem to execute. Here is my main.js: import MyCookiePermissionPlugin from './plugin/my-cookie-permission/my-cookie-permission.pl ...

Is there a way to send a request before opening a new page that doesn't involve using synchronous XMLHttpRequest on the main thread, which is

With the deprecation of synchronous XMLHttpRequest, I am curious about any potential alternatives to achieve a similar behavior. Non-blocking asynchronous XMLHttpRequests may not always be suitable for specific cases. I am specifically referring to a scen ...

Creating a multipart/form-data POST request in Angular2 and performing validation on the input type File

I am working on sending an image (base64) via a POST request and waiting for the response. The POST request should have a Content-Type of multipart/form-data, and the image itself should be of type image/jpg. This is what the POST request should look like ...

Tips for Elevating State with React Router Version 6

Looking for advice on sharing state between two routes in my project. I'm debating whether to lift state up from my AddContact component to either the Layout or App components in order to share it with the ContactList. The Layout component simply disp ...

Obtain the outline shape in ThreeJS (duplicate border)

When working with a geometry, I often need to view it from different angles. For example, if I position my camera from the top, I want to be able to extract the outline of the geometry as a new shape. This allows me to then Extrude this shape further. In R ...

Solving the issue of "localstorage is not defined" in NextJS Redux

Currently, I am working on implementing local storage in Next.js with Redux. In Next.js, components are initially rendered server-side, which means that localStorage or window objects are not available until the rendering occurs in a browser. This issue ...

Tips for detecting when the MDC Snackbar has been closed using JavaScript

I'm currently working with Material Design's Snackbar in combination with VueJS. My goal is to detect when the snackbar has finished closing. The Snackbar object does have a property called isOpen, which allows me to check if the snackbar is ope ...

Regular expression for extracting all JavaScript class names and storing them in an array

In my quest to create a straightforward regex, I aim to spot all class names within a file. The catch is that it should identify them even if there's no space preceding the curly bracket. For example: class newClass {...} This should result in ...

"Encountering a puzzling issue with Django Rest Framework where the path setup is functioning for one link but not for

I'm currently attempting to connect to my MySQL database using the Django REST backend. On my frontend, I'm using Vue with Axios. Specifically, I have a junction table called TeacherSubjectJunction, and I want to access it through the following p ...

Trouble with Material-UI's useMediaQuery not identifying the accurate breakpoint right away

While utilizing the MUI useMediaQuery hook in my React app, I encountered a bug that resulted in errors being thrown due to the initial failure of the hook to recognize the correct breakpoint. Eventually, the page re-renders and displays the correct value. ...

Executing a php function upon onchange event triggered by CKEditor

My task involves invoking a PHP function when I suspect it is being triggered by an ajax call. Utilizing ckeditor, I aim to detect any keyboard activity and believe that using onchange will serve this purpose. Subsequently, I plan to execute a function t ...