4
respostas

Uncaught (in promise) TypeError: Cannot read property 'appendChild' of null

Boa tarde. Quando leio o programa, aparece o seguinte erro, antes mesmo de inserir um novo cliente:

Uncaught (in promise) TypeError: Cannot read property 'appendChild' of null at cliente-service.js:55 at Array.forEach () at cliente-service.js:54 (anonymous) @ cliente-service.js:55 (anonymous) @ cliente-service.js:54 Promise.then (async) (anonymous) @ cliente-service.js:49

Segue meu código (não dividi em vários arquivos, deixei tudo no mesmo arquivo):

// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< CRIA NOVA LINHA >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

const criaNovaLinha = (nome, email) => {

    const linhaNovoCliente = document.createElement('tr')

    // Uma Template Literal precisa estar entre crases.
    const conteudo = `
        <td class="td" data-td>${nome}</td>
        <td>${email}</td>
        <td>
            <ul class="tabela__botoes-controle">
                <li><a href="../telas/edita_cliente.html" class="botao-simples botao-simples--editar">Editar</a></li>
                <li><button class="botao-simples botao-simples--excluir" type="button">Excluir</button></li>
            </ul>
        </td>
    `

    linhaNovoCliente.innerHTML = conteudo

    return linhaNovoCliente
}

//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< LISTA CLIENTES >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

const listaClientes = () => {
    return fetch(`http://localhost:3000/profile`)
    .then(resposta => {
        return resposta.json()
    })
}

// <tbody data-tabela>
const tabela = document.querySelector('[data-tabela]')

listaClientes()
.then(data => {
    data.forEach((elemento) => {
        tabela.appendChild(criaNovaLinha(elemento.nome, elemento.email))
    })
})

// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< CRIA CLIENTE >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

const criaCliente = (nome, email) => {
    return fetch(`http://localhost:3000/profile`, {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json'
        },
        body: JSON.stringify({
            nome: nome,
            email: email,
        })

    })
    .then(resposta => {
        return resposta.body;
    })

}

// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< CADASTRA CLIENTE >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

// <form class="flex flex--coluna" data-form> em cadastra_cliente.html
const formulario = document.querySelector('[data-form]')

formulario.addEventListener('submit', function(evento) {

    evento.preventDefault();

    const nome = evento.target.querySelector('[data-nome]').value
    const email = evento.target.querySelector('[data-email]').value

    criaCliente(nome,email)
    .then(function() {
        window.location.href = '../telas/cadastro_concluido.html'
    })

})
4 respostas

Oi Bruno, tudo certo?

Consegue me mandar aqui seu código HTML também para conseguir te auxiliar melhor? Fico no aguardo, abraços =)

Boa tarde Giovanna. Segue meu lista_cliente.html:

<!DOCTYPE html>
<html lang="pt">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Doguito Petshop | Clientes</title>
    <link href="https://fonts.googleapis.com/css2?family=Montserrat:wght@300;400&display=swap" rel="stylesheet">
    <link href="https://fonts.googleapis.com/css2?family=Pacifico&display=swap" rel="stylesheet"> 
    <link rel="stylesheet" href="../assets/css/base/base.css">
    <link rel="stylesheet" href="../assets/css/componentes/cabecalho.css">
    <link rel="stylesheet" href="../assets/css/lista_cliente.css">
    <link rel="stylesheet" href="../assets/css/componentes/tabela.css">
    <link rel="stylesheet" href="../assets/css/componentes/botao.css">
    <link rel="stylesheet" href="../assets/css/componentes/modal.css">
</head>
<body>
    <header class="cabecalho container">
        <img src="../assets/img/doguitoadm.svg" alt="Logotipo Doguito" class="cabecalho__logo">
        <nav>
            <ul class="cabecalho__lista-navegacao">
                <li class="cabecalho__link"><a href="#">Dashboard</a></li>
                <li class="cabecalho__link"><a href="#">Produtos</a></li>
                <li class="cabecalho__link"><a href="#">Clientes</a></li>
                <li class="cabecalho__link"><a href="#">Pets</a></li>
            </ul>
        </nav>
    </header>

    <main class="clientes-container">
        <table class="tabela">
            <thead>
                <tr>
                    <th class="tabela__coluna--p">Nome</th>
                    <th class="tabela__coluna--g">Email</th>
                    <th class="tabela__coluna--m tabela__alinhamento--direita"><a href="./cadastra_cliente.html" class="botao-simples botao-simples--adicionar">Novo Cliente</a></th>
                </tr>
            </thead>
            <tbody data-tabela>

            </tbody>
        </table>
        <div class="modal-container modal--fechado">
            <article class="modal">
                <h2 class="modal__titulo">
                    Excluir
                </h2>
                <button class="modal__fechar">X</button>
                <p class="modal__texto">Deseja excluir essa entrada?</p>
                <div class="modal__botao-container">
                    <button class="modal__botao modal__botao--confirmar">Excluir</button>
                    <button class="modal__botao">Não excluir</button>
                </div>
            </article>
        </div>
    </main>
</body> 

<script type="module" src="../service/cliente-service.js"></script>


</html>

Segue meu cadastra_cliente.html:

<!DOCTYPE html>
<html lang="pt">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Doguito Petshop | Cadastro de cliente</title>
    <link href="https://fonts.googleapis.com/css2?family=Montserrat:wght@300;400&display=swap" rel="stylesheet">
    <link href="https://fonts.googleapis.com/css2?family=Pacifico&display=swap" rel="stylesheet"> 
    <link rel="stylesheet" href="../assets/css/base/base.css">
    <link rel="stylesheet" href="../assets/css/componentes/cabecalho.css">
    <link rel="stylesheet" href="../assets/css/componentes/cartao.css">
    <link rel="stylesheet" href="../assets/css/cadastra_cliente.css">
    <link rel="stylesheet" href="../assets/css/componentes/inputs.css">
    <link rel="stylesheet" href="../assets/css/componentes/botao.css">
</head>
<body>
    <header class="cabecalho container">
        <img src="../assets/img/doguitoadm.svg" alt="Logo Doguito" class="cabecalho__logo">
        <nav>
            <ul class="cabecalho__lista-navegacao">
                <li class="cabecalho__link"><a href="#">Dashboard</a></li>
                <li class="cabecalho__link"><a href="#">Produtos</a></li>
                <li class="cabecalho__link"><a href="lista_cliente.html">Clientes </a></li>
                <li class="cabecalho__link"><a href="#">Pets</a></li>
            </ul>
        </nav>
    </header>
    <main class="container flex flex--centro flex--coluna">
        <section class="cartao cadastro">
            <h1 class="cartao__titulo">Novo Cliente</h1>
            <form class="flex flex--coluna" data-form>
                <div class="input-container">
                    <input name="nome" id="nome" class="input" type="text" placeholder="Nome" required data-nome>
                    <label class="input-label" for="nome">Nome</label>
                    <span class="input-mensagem-erro">Esse campo não pode estar vazio</span>
                </div>
                <div class="input-container">
                    <input name="email" id="email" class="input" type="text" placeholder="email" required data-email>
                    <label class="input-label" for="email" >email</label>
                    <span class="input-mensagem-erro">Esse campo não pode estar vazio</span>
                </div>
                <button type="submit"class="botao">
                Cadastrar
            </button>
            </form>
        </section>
    </main>
</body>

<script type="module" src="../service/cliente-service.js"></script>

</html>

Segue o que fiz para resolver: criei um script só para cadastrar o cliente, chamado cadastra-cliente.js, que leva o código abaixo:

import {criaCliente} from "../service/cliente-service.js"
/* Precisei separar o código de cadastrar cliente do script cliente-service.js, pois ele trabalha com elementos html
que não existem no lista_cliente.html, o que gera o erro ao rodar o cliente-service.js em cadastra_cliente.html.
Em cadastra_cliente.html chamei só o script do cadastra-cliente.js:
<script type="module" src="../service/cadastra-cliente.js"></script>*/

// <form class="flex flex--coluna" data-form> em cadastra_cliente.html
const formulario = document.querySelector('[data-form]')

formulario.addEventListener('submit', function(evento) {

    evento.preventDefault();

    const nome = evento.target.querySelector('[data-nome]').value
    const email = evento.target.querySelector('[data-email]').value

    criaCliente(nome,email)
    // Ir para a tela de cadastro concluído, após criar o cliente.
    .then(function() {
        window.location.href = '../telas/cadastro_concluido.html'
    })

})

Mas continua apresentando um erro no console quando vou para a tela de cadastra_cliente.html:

cliente-service.js:55 Uncaught (in promise) TypeError: Cannot read property 'appendChild' of null at cliente-service.js:55 at Array.forEach () at cliente-service.js:54

Isso não consegui resolver e não entendi o por quê do erro, uma vez que a tela do cadastra_cliente.html só chama o script do cadastra-cliente.js, e não o script do cliente-service.js, onde está esse Array.forEac:

``data.forEach((elemento) => {
    tabela.appendChild(criaNovaLinha(elemento.nome, elemento.email))
})

})