6
respostas

Não consigo identificar o erro!

Quando clico no botão "Adicionar" aparecente o erro Uncaught TypeError: Cannot read property 'length' of undefined at HTMLButtonElement (form.js:13). O que estou fazendo de errado?

//form.js

var botaoAdicionar = document.querySelector("#adicionar-paciente");
botaoAdicionar.addEventListener("click", function(event) {
  event.preventDefault();

  var form = document.querySelector("#form-adiciona");

  var paciente = obtemPacienteDoFormulario(form);

  var pacienteTr = montaTr(paciente);

  var erros = validaPaciente(paciente);

  if (erros.length > 0) {

    exibeMensagensDeErro(erros);
        return;

  }

  var tabela = document.querySelector("#tabela-pacientes");

  tabela.appendChild(pacienteTr);

  form.reset();

  });

  function obtemPacienteDoFormulario(form) {

    var paciente = {
      nome : form.nome.value,
      peso : form.peso.value,
      altura : form.altura.value,
      gordura : form.gordura.value,
      imc : calculaImc(form.peso.value, form.altura.value)
    }

    return paciente;

  }

  function montaTd(dado, classe) {
    var td = document.createElement("td");
    td.classList.add(classe);
    td.textContent = dado;

    return td;
  }

  function montaTr(paciente) {
    //Cria TR
    var pacienteTr = document.createElement("tr");
    pacienteTr.classList.add("paciente");
    //Cria as TD's e a adiciona dentro da TR
    pacienteTr.appendChild(montaTd(paciente.nome, "info-nome"));
    pacienteTr.appendChild(montaTd(paciente.peso, "info-peso"));
    pacienteTr.appendChild(montaTd(paciente.altura, "info-altura"));
    pacienteTr.appendChild(montaTd(paciente.gordura, "info-gordura"));
    pacienteTr.appendChild(montaTd(paciente.imc, "info-imc"));
    // retorna a TR
    return pacienteTr;
  }

  function validaPaciente(paciente) {

    var erros = [];

    if (paciente.nome.length == 0) {
      erros.push("O nome não pode ser em branco!");
    }

    if (paciente.peso.length == 0) {
      erros.push("O peso não pode ser em branco!");
    }

    if (paciente.altura.length == 0) {
      erros.push("A altura não pode ser em branco!");
    }

    if (paciente.gordura.length == 0) {
      erros.push("A gordura não pode ser em branco!");
    }

    if (!validaPeso(paciente.peso)) {
      erros.push("Peso é inválido!")
    }

    if (!validaPeso(paciente.altura)) {
      erros.push("Altura é inválida!")
    }
  }

function exibeMensagensDeErro(erros) {
  var ul = document.querySelector("#mensagens-erro");
  ul.innerHTML = ""; // Tirar mensagens anteriores

  erros.forEach(function(erro){
    var li = document.createElement("li");
    li.textContent = erro;
    ul.appendChild(li);
  });
}
6 respostas

Alinha 13 é a seguinte:

if (erros.length > 0) {

Boa tarde André,

Este erro significa que tentou usar o método length de algum objeto que não tinha valor.

Você usa lenght em 5 pontos diferentes do seu código, nas linhas:

if (erros.length > 0) {

 if (paciente.nome.length == 0) {

 if (paciente.peso.length == 0) {

 if (paciente.altura.length == 0) {

 if (paciente.gordura.length == 0) {

Ou seja, em algum momento na execução do seu código, ou "erros" ou "paciente", ou alguns dos valores de paciente (nome, peso, altura e gordura) eram indefinidos, ou seja, não existiam, não tinha valor para que o length pudesse ser invocado.

Você sabe usar o debug do navegador? Vai na ferramenta do desenvolvedor, na aba Sources da pra colocar breakpoint no seu código JS e debugar. Um console.log nas alinhas acima de cada uma dessas mostrando o valor de cada um dos objetos envolvidos também lhe ajudará a identificar o problema.

Exemplo:

console.log('erros: ', erros);
if (erros.length > 0) {

Faz um desses para cada uma das suas linhas que usa length.

Bom enquanto eu digitava você já começou a ler melhor o erro, você já sabe que é na linha 13, agora basta você descobrir porque erros está sem valor, e por isso faz o .length falhar. Tente um pouco com o debug como eu sugeri.

Pra te dar um norte, é esta função que está retornando vazio para a variável erros:

var erros = validaPaciente(paciente);

Espero ter ajudado. Abraço.

O problema se encontra na funcão "validaPaciente(paciente)"

Dentro dela é criado um array vazio, e de acordo com os erros que foram detectados, o array vai ganhando elementos (um push para cada erro).

Precisa fazer um return deste array, de outra forma o erro vai persistir. Segue exemplo:

function validaPaciente(paciente) {

    var erros = [];

    if (paciente.nome.length == 0) {
      erros.push("O nome não pode ser em branco!");
    }

    if (paciente.peso.length == 0) {
      erros.push("O peso não pode ser em branco!");
    }

    if (paciente.altura.length == 0) {
      erros.push("A altura não pode ser em branco!");
    }

    if (paciente.gordura.length == 0) {
      erros.push("A gordura não pode ser em branco!");
    }

    if (!validaPeso(paciente.peso)) {
      erros.push("Peso é inválido!")
    }

    if (!validaPeso(paciente.altura)) {
      erros.push("Altura é inválida!")
    }

return erros;
  }

Correto. Você fez tudo certo André, só faltou retornar o array de erros. :)

Descobri o erro do código! O objeto não tinha valor porque eu não escrevi o return erros na função validaPaciente. A função não retornava nada! Agora corrigi o problema e a função funcionou perfeitamente. Além disso, esse bloco de código estava sem o ponto e vírgula:

  if (!validaPeso(paciente.peso)) {
      erros.push("Peso é inválido!");
    }

    if (!validaPeso(paciente.altura)) {
      erros.push("Altura é inválida!");
    }

Obrigado pela respota!

Acho que descobrimos o erro ao mesmo tempo =) Abraços!