Evaluating Angular/Typescript and its capabilities

I seem to be struggling with the concept of how eval functions in TypeScript/Angular. Can someone provide some guidance on how to make eval work in this scenario? Although the logic may not be perfect in this demo program, I just need help figuring out how to use eval to update a dynamic array with a dynamic value.

Check out the code here

export class AppComponent  {
  arrTest1 = [];
  arrTest2 = [];
  arrTest3 = [];

  constructor() {
    this.TestClass.Run("this.arrTest1 = [1];");
    this.TestClass.Run("this.arrTest2 = [2];");
    this.TestClass.Run("this.arrTest3 = [3];");
    console.log(this.arrTest1);   //Logs: [] (I want: [1])
    console.log(this.arrTest2);   //Logs: [] (I want: [2])
    console.log(this.arrTest3);   //Logs: [] (I want: [3])
  };

  TestClass = {
    Run : (pString) => {
      (0, eval)(pString);
      eval(pString);
    }
  };

}

Answer №1

If you execute the following code:

this.TestClass.call("this");

and in the TestCalss:

console.log(eval(pString));

You will notice that it logs the window object. The string this does not retain its context. If you had logged window.arrTest1, you would have obtained the desired outcome.

So...

You should pass the context:

this.TestClass.Run.call(this, "this.arrTest1 = [1]");

And in your TestCalss

TestClass = {
    Run : (pString) => {
      return eval(pString)
    }
};

Why does eval.call(this, pString) not work?

There is a distinction in how eval() operates. eval() is not a conventional javascript function. As explained here: How override eval function in javascript?

As you may have already attempted, something like this:

(0, eval)(pString); // this is an indirect call to eval

What constitutes an indirect call??

According to ES5, all of these are indirect calls and should execute code in global scope

The global scope in your scenario will be null, since typescript does not inherently provide a global scope. (To the best of my knowledge)

For a detailed explanation about eval, please refer to:

In accordance with the above resource, the following are examples of indirect eval calls :

(1, eval)('...')
(eval, eval)('...')
(1 ? eval : 0)('...')
(__ = eval)('...')
var e = eval; e('...')
(function(e) { e('...') })(eval)
(function(e) { return e })(eval)('...')
(function() { arguments[0]('...') })(eval)
this.eval('...')
this['eval']('...')
[eval][0]('...')
eval.call(this, '...')  <-- This is your case.
eval('eval')('...')

Another passage from the article:

Not understanding what’s going on, some people unfortunately come up with rather monstrous solutions like eval.call(window, '...'), window.eval.call(window, '...') and even scarier combinations. All of those are, once again, nothing but indirect eval calls.

There's also a very insightful section explaining why (0, eval)(pString) is considered an indirect call. Please review this. Unfortunately, I could not find a solid justification for why eval.call(this, '...') is seen as indirect. Perhaps we just need to accept the notion that eval() is not a traditional function.

Answer №2

Important note: Proceed with caution when using the eval function!

However, in the spirit of helpfulness, I will demonstrate how to make your code functional. To specify the context of your eval function, you can utilize the call JavaScript function in the following manner:

this.TestClass.Run.call(this, "this.arrTest2 = [2];");

Additional tip: It's generally advisable to avoid using the eval function altogether. You can articulate your issue without disclosing the entire code and seek assistance in resolving it.

UPDATE: For achieving dynamic arrays or values, consider employing a simple object and dynamically adding attributes to it. For instance, if your object is labeled as A, you can create an object attribute dynamically using A[varName].

Answer №3

Dealing with a similar issue involving eval, I found a solution by using the following Immediately Invoked Function Expression (IIFE).

The expressions I was working with were being sent from a backend system in the form of something like: "Client === 123", and there was no possibility to modify them.

As "eval" does not directly comprehend these expressions, especially considering that in TypeScript member variables are accessed using the "this" keyword (e.g., "this.Client"), one workaround is to encapsulate the necessary variables within a function and then call eval.

  testEval(expression: HTMLInputElement) {
    const result = (() => {
      const Client = this.clientNumber;
      return eval(expression.value);
    })();

    this.expressionResult = `expression: [${expression.value}], result: [${result}]`;
  }

Check out the StackBlitz Demo for more information

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

Facing issues updating the parent state value while using NextJs with React

I recently started working with NextJS and React, and I'm using trpc along with useQuery to fetch a list of users. After fetching the user list, I need to filter it based on the user's name. Below is a snippet of the code I've been working ...

Angular continually monitors changes for dom-to-image and generates countless renders

I am trying to implement a feature in my Angular 4 application where child-components render wallpapers for themselves using dom-to-image-more. The issue arises when I try to dynamically render these child-components using *ngFor. The parent component h ...

Tips for adding icon to mat-sort-header within mat-table

Hi there, I'm currently working with mat-table in Angular and I have a question regarding adding a custom icon to the mat-sort-header. The issue I am facing is that when I click on the icon, the table gets sorted which is not the behavior I want. Belo ...

Show array elements in Angular framework

I need help with displaying a list that contains three columns: menu, menuItem, and order. The desired display format is to show menu and menuItem ordered by order as follows: Menu 1 : order 200 Menu 2 : order 230 Menu 3 : order 250 Menu item 1 : order 2 ...

Encountering a failure in library construction while using Angular 9

Currently, I am in the process of updating this library https://github.com/flauc/angular2-notifications from Angular 2+ to Angular 9. The initial error was related to the ModuleWithProviders becoming a generic type, which I have successfully addressed. Ad ...

Avoid triggering onClick events on all rows when clicking, aim for only one row to be affected per click

I have a unique situation where I have a table containing rows with a button in each row. When this button is clicked, it triggers an onClick event that adds two additional buttons below the clicked button. The Issue: When I click on a button, the onClick ...

What is causing the issue with TypeScript's React.createRef() and its compatibility with the material-ui Button element?

Running on React version 16.13.1, my component class includes a Material-UI Button component and a RefObject to access the button element. class Search extends React.Component<any, any>{ constructor(props: any) { super(props) this.streetV ...

Error: Unable to call function onPopState from _platformLocation due to TypeError

After building an angular application, I encountered a strange issue where it runs smoothly in non-production mode but throws an error when running with --prod: Uncaught TypeError: this._platformLocation.onPopState is not a function I have double-checked ...

Creating a component with the name "c-name" is not possible because the specified module does not exist

Current working directory /src/app Directory of app.module.ts /src/app/app.module.ts Adding a new component to this directory catalog/single/configurator/[new component here] Attempt #1 to add a component ng g c catalog/single/configurator/details-popo ...

Utilizing Filestack in Angular 2

I'm currently working on integrating image uploading functionality into my Angular 2 App, and I have decided to utilize Filestack (formerly filepicker.io) for storing the images. Following Filestack's recommendations, I added the necessary script ...

Leveraging the keyof keyword to access a specific property within a type

I have a variety of types that I need to work with. For example: type Type = { prop1: number; prop2: string; prop3: someOtherType } type Props = keyof Type I am aware that using an "indexed access type" allows me to extract the type of propN, ...

What role do the esm directories serve within Angular 2 modules?

Currently, I am working with Angular2 RC4 and using the following packages: "@angular/common": "2.0.0-rc.4", "@angular/compiler": "2.0.0-rc.4", "@angular/core": "2.0.0-rc.4", "@angular/forms": "0.2.0", "@angular/http": "2.0.0-rc.4", ...

Updating array values in Angular 4

I am working with: button *ngFor="let button of buttons" (click)="changeValue()" In my project: export class Home { howMany: number = 10; zoom: number = 5; buttons = [ { howMany: 40, zoom: 10 }. { howMany: 100, zoom: 2 }, { howMany: ...

Advancing the utilization of custom Angular input fields

I've developed a unique Angular input element that utilizes a textarea as its primary input field. Is there a way for me to pass along the enter key event to the main form? ...

Encountering an Error in Angular with Jest: TypeError Unable to Access Property 'ngModule' from null

Challenge I have been trying to implement Jest testing for my Angular application. Following the guidelines provided by jest-preset-angular, I encountered an error when running tests with Bazel using this target: FAIL services/client/src/app/app.componen ...

Tips for efficiently managing angular route subscriptions and leveraging parameters for simultaneous http requests

I am seeking the best solution for the following situation: My goal is to trigger two parallel http requests when an Observable from the route parameters subscription fires. I attempted to use switchMap in combination with forkJoin, but unfortunately it ...

Unique styling implementation for element situated underneath Angular 6 router-outlet

I'm currently working on implementing router transitions in my Angular application, and I've encountered an unusual problem. The styling for the router-outlet element is being applied to the element that comes after it in the DOM hierarchy. Here ...

Tips for incorporating recursive HTTP requests into an Angular2 service to efficiently retrieve data in advance

In my Angular project, I am using a service to fetch data from an external API. However, the API has a limit of 100 records per request and I can only determine the total number of records available after fetching the first batch. The response structure o ...

Tips for assigning a JSON object as the resolve value and enabling autosuggestion when utilizing the promise function

Is there a way to make my promise function auto-suggest the resolved value if it's a JSON object, similar to how the axios NPM module does? Here is an example of how axios accomplishes this: axios.get("url.com") .then((res) => { Here, axios will ...

retrieving class instances from a Firebase database

I have a new group called GroupA group A { value1: string; value2: string; total(): number { return value1 + value2; } } I want to store instances of GroupA in my database, but when I retrieve them, they are in Object format which does not a ...