How can I input a 0 or empty value on the prompt and don't let the action returned by this value be the same as the one returned by the cancel button?

Viewed 53

I was making a simple calculator with JavaScript and, after I finished it, I started to look for some parts of my code which it could be improved. I had been trying to make an alert show up if the number 0 or empty was inputted in the prompt and it was working, but then I clicked the CANCEL button in the prompt and the same output happened. My question is how can I change the code below to be able to have one output for the 0 or empty value and another one for the CANCEL button?

const operacao = Number(
  prompt(
    `Qual a sua operação hoje? 
    1 - Soma (+)
    2 - Subtração (-)
    3 - Multiplicação (*)
    4 - Divisão (/)
    5 - Potenciação (^)
    6 - Raiz (*/)
    7 - Logaritmo natural (log)
    8 - Divisão inteira (resto) 
    `,
    ["Digite aqui!"]
  )
);
if (operacao == false) {
  if (confirm("Quer mesmo sair?") == true) {
    Window.close();
  } else {
    calculadora();
  }
} else if (operacao < 1 || operacao > 8) {
  alert("Por favor, escolha um número que retorne uma operação!");
  calculadora();
} else if (!operacao) {
  alert("Por Favor, digite um número válido!");
  calculadora();
}
1 Answers

Per the prompt docs, "If the user clicks the Cancel button, this function returns null." The first thing you do with the result of prompt is coerce it into a Number. Number(null) === 0, so when the user presses Cancel, all of the conditions are evaluated against 0.

However, immediately coercing to Number is the wrong thing to do, because you are losing information. Once you've done so, there's no way to tell the difference between Cancel and typing 0. Instead, we're going to remove the coersion as follows:

const promptResult = prompt(
  `Qual a sua operação hoje? 
    1 - Soma (+)
    2 - Subtração (-)
    3 - Multiplicação (*)
    4 - Divisão (/)
    5 - Potenciação (^)
    6 - Raiz (*/)
    7 - Logaritmo natural (log)
    8 - Divisão inteira (resto) 
    `,
  ["Digite aqui!"]
);

Then, we're going to add an outer check to your conditionals:

if (promptResult === null) { 
  // do whatever should happen when the user presses cancel
} else {
  const operacao = Number(promptResult);
  // the rest of your code goes here
...

Also, note per the docs that Number("invalid number") === NaN, so where you say else if (!operacao), it's clearer (though no less correct) if you check explictly for NaN, i.e. else if (operacao === NaN).

Related