3
respostas

"TypeError: Cannot read property 'length' of undefined" ao enviar um POST

Quando envio um POST recebo a seguinte mensagem de erro:\

TypeError: Cannot read property 'length' of undefined
    at Atendimento.adiciona (C:\Users\NINO\Documents\Dev\Alura\Node Rest\models\atendimentos.js:46:35)
    at C:\Users\NINO\Documents\Dev\Alura\Node Rest\controllers\atendimentos.js:23:21

Código do models/atendimentos:

const { default: axios } = require("axios")
const moment = require("moment")
const conexao = require("../infraestrutura/database/conexao")
const repositorio = require("../repositorios/atendimentos")

class Atendimento {
    constructor() {
        //já vai retornar true ou false
        this.dataEhValida = ({data, dataCriacao}) => moment(data).isSameOrAfter(dataCriacao)
        this.nomeEhValido = tamanho => tamanho >= 5

        this.valida = ({...parametros}) => {
            this.validacoes.filter(campo => {
                const {nome} = campo
                const parametro = parametros[nome]

                return !campo.valido(parametro)
            })
        }

        this.validacoes = [
            {
                nome: "data",
                valido: this.dataEhValida,
                mensagem: "A data do agendamento deve ser menor do que a data de criação."
            },
            {
                nome: "cliente",
                valido: this.nomeEhValido,
                mensagem: "O nome do cliente deve conter no mínimo cinco caracteres"
            }
        ]
    }

    adiciona(atendimento) {
        const dataCriacao = moment().format("YYYY-MM-DD HH:MM")
        const data = moment(atendimento.data, "DD/MM/YYYY").format("YYYY-MM-DD HH:MM")

        //vai verificar os objetos cujas chaves "valido" sejam == false
        const parametros = {
            data: {data, dataCriacao},
            cliente: {tamanho: atendimento.cliente.length}
        }

        const erros = this.valida(parametros)
        const exitemErros = erros.length

        if(exitemErros) {
            return new Promise((resolve, reject) => {
                reject(erros)
            })
        } else {
            const atendimentoDatado = {...atendimento, dataCriacao, data}

            return repositorio.adiciona(atendimentoDatado)
                .then((resultado) => {
                    const id = resultado.insertId
                    return {...atendimento, id}
                })
        }
    }
    //outros métodos...
    }

module.exports = new Atendimento()

Código do controllers/atendimentos:

const Atendimento = require("../models/atendimentos.js")

module.exports = app => {
(...)

    app.post("/atendimentos", (req, res) => {
        const atendimento = req.body

        Atendimento.adiciona(atendimento)
            .then(atendimentoCadastrado => res.status(201).json(atendimentoCadastrado))
            .catch((erros) => {
                res.status(400).json(erros)
                //res.status(400).redirect("https://http.cat/400")
            })
    })

//outras funções do CRUD...
}
3 respostas

Bom, pelo que entendi, na linha 46, você está tentando pegar o tamanho de erros...

const exitemErros = erros.length

Bom, tente usar um

console.log(`Erros: ${erros} Erros Length: ${erros.length}`)

Ou:

console.log("Erros: " + erros + "Erros Length: " + erros.length)

e me mostre o que está aparecendo em erros

Observação: Para saber mais sobre o acento agudo, você pode ver a documentação oficial do JavaScript https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/Template_literals

Eu estou com o mesmop problema. Tentei o console log e ele me trás o valor:

Atendimento.Cliente = 11
TypeError: Cannot read property 'length' of undefined
    at Atendimento.adiciona (D:\Adriana\02. Alura\08.API\models\atendimento.js:49:36)
    at D:\Adriana\02. Alura\08.API\controllers\atendimentos.js:18:21
    at Layer.handle [as handle_request] (D:\Adriana\02. Alura\08.API\node_modules\express\lib\router\layer.js:95:5)
    at next (D:\Adriana\02. Alura\08.API\node_modules\express\lib\router\route.js:137:13)
    at Route.dispatch (D:\Adriana\02. Alura\08.API\node_modules\express\lib\router\route.js:112:3)
    at Layer.handle [as handle_request] (D:\Adriana\02. Alura\08.API\node_modules\express\lib\router\layer.js:95:5)
    at D:\Adriana\02. Alura\08.API\node_modules\express\lib\router\index.js:281:22
    at Function.process_params (D:\Adriana\02. Alura\08.API\node_modules\express\lib\router\index.js:335:12)
    at next (D:\Adriana\02. Alura\08.API\node_modules\express\lib\router\index.js:275:10)
    at D:\Adriana\02. Alura\08.API\node_modules\body-parser\lib\read.js:130:5

Código:

const axios = require('axios')
const moment = require('moment')
const conexao = require('../infraestrutura/database/conexao')
const repositorio = require('../repositorios/atendimentos')

class Atendimento{

    constructor(){

        //validação de regras de negócio
        this.dataEhValida = ({data, dataCriacao})=> moment(data).isSameOrAfter(dataCriacao)
        this.clienteEhValido = ({ tamanho} ) => tamanho >= 5

        this.valida = (parametros) => {
            this.validacoes.filter(campo => {
                const {nome} = campo
                const parametro = parametros[nome]
                return !campo.valido(parametro)
            })
        }

        this.validacoes = [
            {
                nome : 'data',
                valido : this.dataEhValida,
                mensagem : 'Data deve ser maior ou igual a data atual'
            },
            {
                nome: 'cliente',
                valido : this.clienteEhValido,
                mensagem : 'Nome deve ter menos de 5 caracteres'
            }
        ]

    }

    adiciona(atendimento){
        const dataCriacao = moment().format('YYYY-MM-DD HH:MM:SS')
        const data = moment(atendimento.data, 'DD/MM/YYYY').format('YYYY-MM-DD HH:MM:SS')

        console.log(`Atendimento.Cliente = ${atendimento.cliente.length}`)

        const parametros ={
            data: { data, dataCriacao },
            cliente: { tamanho: atendimento.cliente.length }
        }

        const erros = this.valida(parametros)
        const existemErros = erros.length 

        if(existemErros){
            return new Promisse((resolve,reject)=>{
                reject(erros)
            })
        }else{
            const atendimentoDatado = {...atendimento, dataCriacao, data}

            return repositorio.adiciona(atendimentoDatado)
                .then((resultados) => {
                    const id = resultados.insertId
                    return {...atendimento, id}
                })
        } 
    }

    lista(res){
        const sql = 'SELECT * FROM atendimentos'

        conexao.query(sql, (erro, resultados) =>{
            if(erro){
                res.status(400).json(erro)
            }else{
                res.status(200).json(resultados)
            }
        })
    }

    buscaPorId(id, res){
        const sql = `SELECT * FROM atendimentos WHERE id=${id}`

        //fazendo conexão com DB
        conexao.query(sql, async (erro, resultados) =>{
            const atendimento = resultados[0]
            const cpf = atendimento.cliente

            if(erro){
                res.status(400).json(erro)
            }else{
                const { data } = await axios.get(`http://localhost:8082/${cpf}`)
                atendimento.cliente = data
                res.status(200).json(atendimento)
            }
        })
    }


    altera(id, valores, res){

        if(valores.data){
            valores.data = moment(valores.data, 'DD/MM/YYYY').format('YYYY-MM-DD HH:MM:SS')
        }

        const sql = 'UPDATE Atendimentos SET? where ID=?'

        conexao.query(sql, [valores, id], (erro, resultado) => {
            if(erro){
                res.status(400).json(erro)
            }else{
                res.status(200).json({...valores, id})
            }
        })
    }

    deleta(id, res){
        const sql = 'DELETE FROM ATENDIMENTOS WHERE ID=?'

        conexao.query(sql,id, (erro, resultado)=>{
            if(erro){
                res.status(400).json(erro)
            }else{
                res.status(200).json({id})
            }
        })
    }
}

module.exports = new Atendimento

Eu estou com o mesmo problema e ao trocar a função valida para a mesma do repositório do github disponibilizado do curso, o erro sobre length undefined não retornou mais. https://github.com/alura-cursos/nodejs-2/blob/aula-5-nova/models/atendimentos.js

this.valida = parametros =>
            this.validacoes.filter(campo => {
                const { nome } = campo
                const parametro = parametros[nome]

                return !campo.valido(parametro)
            })

Os valores passados voltaram a ser validados normalmente, e se houvesse algum erro, o json de erros era retornado na requisição.