Removing eval from code

What would I replace it with?

jsfiddle says it shouldn’t be used.

https://jsfiddle.net/prxLs103/

function display(){
  const value = document.getElementsByTagName("input")[0].value;
  document.getElementById("output").innerHTML = eval(value);
}

Instead of having the answer appear as you are typing.

Can it be set up like this instead?

After you put the equation in, then you click calculate?

https://jsfiddle.net/rcf7ex4L/4/

The reason why eval is not allowed is that there are far too many security issues when using the eval statement.

Instead, there are plenty of calculator parsers out there that can be used instead. For example:

https://jorendorff.github.io/calc/docs/calculator-parser.html

That way you can parse it using parseExpr(value) which in your code might look like:

document.getElementById("output").innerHTML = parseExpr(value);

Would I be able to set up that code to work with this?

https://jsfiddle.net/rcf7ex4L/4/

In that case you would be wanting to get the calculator code from a cdn so that it can be added into resources.

Here’s one from https://cdnjs.cloudflare.com/ajax/libs/mathjs/9.4.4/math.min.js
The details are found at https://mathjs.org/

But basically, eval can be replaced with math.evaluate instead.
getElementById('result').value = math.evaluate(getElementById('input').value)

The minimal change code is found at https://jsfiddle.net/y34te1aL/

I’ve also moved the inline onclick code out of the HTML and into the JS section and tidied up the JS code, resulting in the following:

/*global math */
const button = document.querySelector("button");
button.addEventListener("click", function () {
    const input = document.querySelector("#input");
    const result = document.querySelector("#result");
    result.value = math.evaluate(input.value);
});

The updated code can be found at https://jsfiddle.net/y34te1aL/1/

1 Like

Can it work without the need foe this?

https://cdnjs.cloudflare.com/ajax/libs/mathjs/9.4.4/math.min.js

You can make your own math evaluator, but that’s too much work.
Someone has done it properly so use that instead.

Could this one be cleaned up, or is that a lot of work?
https://jsfiddle.net/295fe3g1/

or maybe I could look for a different one.

Can these 3 input boxes be reduced to 1

https://jsfiddle.net/r02ugh9v/3/

function calc() {
    var textType = Node.textContent ? 'textContent' : 'innerText',
        num1 = parseFloat(document.getElementById('num1').value) || 0,
        num2 = parseFloat(document.getElementById('num2').value) || 0,
        result = document.getElementById('result');
    switch (document.getElementById('op').value.replace(/\s/g,'')){
        case '+':
            result[textType] = num1 + num2;
            break;
        case '-':
            result[textType] = num1 - num2;
            break;
        case '*':
            result[textType] = num1 * num2;
            break;
        case '/':
            result[textType] = num1 / num2;
            break;
            default:
                result[textType] = ''
                break;
    }
}

Like how it works here:
https://jsfiddle.net/295fe3g1/

I’m sick as a dog with a cold. There is no more from me today, or for the rest of the week.

Feel better and get well soon.

1 Like

I found this code, I would just need help getting rid of eval.

https://jsfiddle.net/0exLba97/

function calc() {
  let equation = document.getElementById('equation').value || 0;
  let result = document.getElementById('result');

  // Make sure you only have numbers, operators and parenthesis
  let matches = equation.match(/[\d\+\-\/\*\(\)]/g);

  if (matches && matches.length == equation.length) {
    result.innerText = eval(equation);
  } else {
    result.innerText = "Error";
  }
}

Here it is without eval, it would just need to be improved.

https://jsfiddle.net/1cjkh7mo/

function calc() {
  let equation = document.getElementById("equation").value || 0;
  let result = document.getElementById("result");

  // Make sure you only have numbers, operators and parenthesis
  let matches = equation.match(/[\d\+\-\/\*\(\)]/g);

  // Get a clean equation from allowed chars
  let clean = matches.join("");
  console.log(clean);

  // Get the numbeers and operator separately
  let operators = clean.split(/\d+/).filter((op) => op !== "");
  let numbers = clean.split(/[\+\-\*\/]/).map(n=>parseInt(n));
  console.log(operators, numbers);

  // Start with the first number then calculate based on the operator
  let temp = numbers[0];
  operators.forEach(function (op, index) {
    switch (op) {
      case "+":
        temp += numbers[index + 1];
        break;
      case "-":
        temp -= numbers[index + 1];
        break;
      case "*":
        temp = temp * numbers[index + 1];
        break;
      case "/":
        temp = temp / numbers[index + 1];
        break;
    }
  });

  result.innerText = temp;
}

Why are you needlessly reinventing things? Code libraries are designed to be reused without needing to repeat anything.

You already have a fully working system using math.evaluate()
https://jsfiddle.net/y34te1aL/

What’s stopping you from using that?

1 Like