My subtraction calculus in Javascript is returning a "Nan"

Asked

Viewed 64 times

2

I am a beginner in Javascript and I was doing a change calculation program. I used the following code:

<h1>Calculando o Troco</h1>
<input type="button" value="Comprar produto" onclick="clique()">
<script>
  function clique(){
    var produto = prompt('Qual produto você quer comprar?')
    var custo = parseFloat(prompt(`Quanto custa o(a) ${produto} que você está comprando?`)).toFixed(2).replace('.', ',')
    var valor = parseFloat(prompt(`Qual foi o valor que você deu para pagar o(a) ${produto}?`)).toFixed(2).replace('.', ',')
    var troco = parseFloat(valor - custo).toFixed(2).replace('.', ',')
    alert(`Você comprou um(a) ${produto} que custou R$ ${custo}. Você deu R$ ${valor} em dinheiro e vai receber R$ ${troco} de troco. Volte sempre!`)
  }
</script>

When executed, the alert displays the following message:

You bought a (a) bread that cost R $ 5,00. You gave R $ 10,00 in cash and will receive R$ NaN change.

I’ve tried without the parseFloat, without the replace, calculating within the placeholder, but nothing works.

What I did wrong?

  • It worked, thank you very much! :)

  • I think it’s worth an explanation a little better than a simple comment. I put a response and hope it helps you :)

1 answer

3

It turns out that subtraction of values can do the parse both strings (valor and custo) following the format 0.00 (for example) or string that has integer format '0'. He can identify the . floating point number.

In the case, the prompt returns a string, and this conversion you use makes sense, because we really should treat any input data, mainly user data, but this is for another time.

See below:

// string de um número flutuante
const str = '2.88'

// exibe o número 2.88 e o tipo é "number"
console.log(parseFloat(str), typeof parseFloat(str))

Now, when you used the toFixed(2), a type conversion was made 'number' for 'string'. See the example for the string '2':

let value = parseFloat('2')

// antes era "number"
console.log(value, typeof value)

// agora converteu para "string" por causa do toFixed
value = value.toFixed(2)

console.log(value, typeof value)

The problem of NaN was because of the replace('.', ','). One or more strings that had the format '2.00' can be easily accepted by subtraction operation, since the - converts both strings to numbers, soon something like '2.00' is understood as floating point 2.00 after being converted, but '2,00' is not because of ,:

let value = parseFloat('2').toFixed(2)

// antes era "2.00"
console.log(value)

// agora transformou '2.00' em '2,00'
value = value.replace('.', ',')
console.log(value)

// aqui eu demonstro que '2.00' - '2.00'
// funciona normalmente

// ambos sao convertidos para numeros
console.log('2.00' - '2.00')

// agora '2,00' é entendido como string
// não possível de ser convertida em número,
// logo essa operação de subtração irá falhar.

// ocorre um erro por causa do '2,00' e retorna
// NaN
console.log('2,00' - '2.00')

In your case, the use of replace before the time, caused the error. Try to learn from an early age that what you did was format a result to display to the user, this should be usually, the last step in the treatment of values, that is, you should perform all operations and only at the end, process the data and display them in the format that the user expects.

Remove the replace of the values of custo and valor, perform the required operations first, and finally format to display the result:

<h1>Calculando o Troco</h1>
<input type="button" value="Comprar produto" onclick="clique()">
<script>
  function clique(){
    var produto = prompt('Qual produto você quer comprar?')
    
    // remova replace
    var custo = parseFloat(prompt(`Quanto custa o(a) ${produto} que você está comprando?`)).toFixed(2)
    var valor = parseFloat(prompt(`Qual foi o valor que você deu para pagar o(a) ${produto}?`)).toFixed(2)
    
    // realize a opercao valor - custo primeiro   
    var troco = parseFloat(valor - custo).toFixed(2)
    
    // depois formate o valor para exibir
    // deixe o código um pouco mais semantico
    var trocoFormatado = troco.replace('.', ',')
    
    alert(`Você comprou um(a) ${produto} que custou R$ ${custo}. Você deu R$ ${valor} em dinheiro e vai receber R$ ${trocoFormatado} de troco. Volte sempre!`)
  }
</script>

Browser other questions tagged

You are not signed in. Login or sign up in order to post.