Solucionado (ver solução)
Solucionado
(ver solução)
2
respostas

Uncaught TypeError: Cannot read property 'value' of null at HTMLButtonElement.calcImc

Estava refazendo os programas anteriores do Curso 1 de lógica de programação com base na aula 08, atividade 01. Insira aqui a descrição dessa imagem para ajudar na acessibilidadeApós verificar o console fui recebido com o erro "Uncaught TypeError: Cannot read property 'value' of null at HTMLButtonElement.calcImc"

Como posso corrigir ?

2 respostas
solução!

Bom dia, Gabriel! Tudo bem?

Ele está acontecendo isso por causa do queryselector dos dois inputs. Vou fazer uma explicação sobre como fazer o que você está pretendendo:


Por que document.querySelector() não funciona?

O querySelector() retorna o primeiro elemento que corresponda um selector CSS no documento. CSS (Cascading Style Sheets) é um mecanismo para adicionar estilo a um documento web.

Seus seletores podem ser o nome do elemento (tag), sua classe ou id. Por isso ele funciona pra selecionar inputs e buttons, por exemplo.

document.querySelector("button");
document.querySelector("input");

Mas você está trabalhando com o atributo name, ele não reconhece isso e retorna null e o erro que você viu.


Trabalhando com document.getElementsByName()

Com o método document.getElementsByName() você vai conseguir selecionar elementos com o nome em específico que você quer:

 var weight = document.getElementsByName("peso");
 var height = document.getElementsByName("altura");

Apesar dele servir pra isso e não retornar mais null, você vai ver que ele não faz o calculo do IMC. Isso acontece pois ele retornou uma lista de valores daquele input, se usar console.log(weight) você consegue visualizar isso:

NodeList da variável weight

E para acessar os valores (value) desse input, precisamos acessar o que tem dentro da posição 0 dessa lista, então vamos acrescentar algo na definição da variável:

   var weight = document.getElementsByName("peso")[0];
   var height = document.getElementsByName("altura")[0];

Agora, com o weight.value e height.value ele vai conseguir usar os valores que colocamos nesse input.

Mesmo assim, não está aparecendo no alert() o valor do imc.


Concatenação

Lembra que os formulários são do tipo texto? Ou seja, nosso código está recebendo os valores weight e height como strings.

Apesar de o JavaScript ser uma linguagem fracamente tipada e conseguir fazer operações de subtração, divisão e multiplicação envolvendo strings, ele não entende uma operação de soma envolvendo strings (nossa conta do IMC está funcionando agora, pois nela não houve nenhuma soma.). Para receber como números, teriamos que trocar o type para "number" e por fim, ao invés de selecionar com ".value" iriamos usar o ".valueAsNumber".

No lugar da soma, ele junta as duas strings, e esse processo é chamado de concatenar. O que imprime no alert é uma string. Pra unir a nossa escrita com a variável imc que também é uma string, vamos usar o operador "+".

 alert("Seu imc é: " + imc)

Código final

<meta charset="UTF-8">
<input type="text" name="peso" placeholder="Digite seu peso"/>
<br>
<br>
<input type="text" name="altura" placeholder="Digite sua altura">
<br><br>
<button>Clique aqui</button>

<script>

   var weight = document.getElementsByName("peso")[0];
   var height = document.getElementsByName("altura")[0];


   function calcImc() {
    var imc = Math.round(weight.value / (height.value * height.value));
    alert("Seu imc é: " + imc)
   }

   var button = document.querySelector("button")
   button.onclick = calcImc;


</script>

Há também outras maneiras de usar mais de um input, usando class e/ou id. Com esses, usamos o método getElementsByClassName() ou getElementsById().

Espero que agora tenha ficado um pouco mais claro de como fazer funcionar, nos outros cursos você vai aprender melhor sobre como receber mais de um input =)

Bons estudos!

Consegui resolver e entender tudo certinho. Muito obrigado pela ótima explicação :)