8
respostas

Lista não achada no EJS

Estou fazendo um código semelhante, mas mesmo passando a lista via JSON, o ejs reclama. Não acha a lista; variável de iteração. Alguém vê qual meu erro?

var conn = require('./infra/connFactory');
var pessoas = require('./infra/pessoas');

console.log('entrei');

function DBconn(app){

    app.get('/cpf', function(req,res){
        var conn = connFactory();

        pessoas.listar(conn, function(err,results){
            res.render('/views/list',{ lista : results });
        });
        /*
        conn.query('select * from pessoas', function(err, results){
            res.render('./views/cpfList',{lista:results});
        });
        */
        conn.end();
    });
}

module.exports = function(){
    return DBconn;
}
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>List Page</title>
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" type="text/css" media="screen" href="/stylesheet/cpf.css" />
</head>
<body>
    <table>
        <tr>
            <td>nome</td>
            <td>cpf</td>
            <td>situacao</td>
        </tr>
        <%for(var i=0;i<lista.length;i++) {%>
            <tr>
                <td><%=lista[i].nome%></td>
                <td><%=lista[i].cpf%></td>
                <td><%=lista[i].situacao%></td>
            </tr>
        <%}%>
        <tr>
        </tr>
    </table>
</body>
</html>
8 respostas

Pessoal, talvez meu problema esteja com o código abaixo.

var express = require('express');
var router = express.Router();
/* GET home page. */
router.get('/', function(req, res, next) {
  res.render('index', { title: 'Express' });
});

//nesse get eu quero listar e pegar as coisas do banco
/* GET list page. */
router.get('/List', function(req, res, next) {
  res.render('list', { title: 'Cadastrados' });
});
//aqui eu quero inserir no banco
/* POST home page. */
router.post('/cpf', function(req, res, next) {
  var nome = req.body.nome;
  var cpf = req.body.cpf;
  var situacao = req.body.situacao;
  require('../db').db(nome, cpf, situacao,
    res.redirect('/'));

});
module.exports = router;

O segundo GET me manda direto para a página de listar, e claro, não há menção a conexão ao BD, as variáveis... Creio que preciso direcionar aqui, de alguma maneira, o módulo que exporta o BDConn. Se for isso, alguém sabe como o faço?

Olá, Marcos.

Não ficou bem claro qual a URL que você está chamando... É a http://localhost:3000/cpf?

Outra dúvida: qual é a mensagem de erro?

embora eu tenha essa url, a que eu chamo é http://localhost:3000/list.

e o erro é esse:

C:\Users\Vinicius\Desktop\desafio\views\list.ejs:17 15|

situacao 16| >> 17| <%for(var i=0;i 18| 19| <%=lista[i].nome%> 20| <%=lista[i].cpf%> lista is not defined

Fala, Marcos!

Se você chama a URL http://localhost:3000/list, ele vai passar pelo código abaixo:

router.get('/List', function(req, res, next) {
  res.render('list', { title: 'Cadastrados' });
});

Só que, nesse código, apenas é definido o parâmetro title para a view e não o lista. Por isso, ele diz que não está definido!

Perfeito! O problema agora é que tem que haver algo antes do render. Preciso conectar ao BD e listar o que tem lá. meus módulos estão assim:

db.js

var conn = require('./infra/connFactory');
var pessoas = require('./infra/pessoas');

function DBconn(app){
    app.get('/cpf', function(req,res){
        var conn = connFactory();

        pessoas.listar(conn, function(err,results){
            res.render('/views/list',{ lista : results });
        });
        /*
        conn.query('select * from pessoas', function(err, results){
            res.render('./views/cpfList',{lista:results});
        });
        */
        conn.end();
    });
}

module.exports = function(){
    return DBconn;
}

connFactory.js

var mysql = require('mysql');
 function createDBConn(){
    return mysql.createConnection({
        host: 'localhost',
        user : 'root',
        password: 'root',
        database : 'challenge'
    });
}

module.exports = function(){
    return createDBConn;
}

pessoas.js:

module.exports = function(){
    this.listar = function(conn,callback){
        conn.query('select * from pessoas');
    }
    return this;
}

Olá, Marcos.

Naquele outro seu arquivo com as rotas, você precisaria importar o seu módulo db.js e invocá-lo passando o router.

Algo como:

var express = require('express');
var router = express.Router();
var db = require('./db');
db(router);

Na verdade, o vídeo Carregamento automático dos módulos da aula 2 usa uma outra abordagem com a biblioteca express-load para chamar os seus módulos de rotas automaticamente.


Marcos, posso dar um feedback sobre o código?

O nome do módulo db.js e da função DBconn estão meio estranhos.

No curso, a gente chama esse tipo de módulo que associa uma rota a uma lógica que chama o banco de dados de route.

Seguindo o padrão da aula, você criaria uma pasta routes e colocaria o arquivo pessoas.js.

Lá no diretório infra, você chamaria de pessoasDAO.js.

Algo que poderia ajustar no código é o seguite, quando acessa a rota "/cpf", ele vai carregar a view "list", passando uma variável "lista" após consultar o banco de dados. Porem, o "results" somente vai existir se houver sucesso na consulta ao banco, se houver algum erro, ela não vai existir, ou seja, vai estar undefined.

Neste caso, o ideal seria tratar o erro e criar um valor padrão para esta situação, ou então redirecionar para uma página de erro.

Um exemplo de como tratar o erro:

(... )
 pessoas.listar(conn, function(err,results){
            var resultado = []; //Array vazio
            if (err){
                /retorno é o array vazio
            } else {
                resultado = results; //Retorno banco    
            }
            res.render('/views/list',{ lista : resultado });
        });

Marcos, verifique quais dados estão retornando do banco. No meu caso o Ejs acusava que a variável não possuía a propriedade length.

No fim das contas estava fazendo a query para uma tabela inexistente no meu banco