5: Recorrer entradas con forEach en EJS
馃幆 Objetivo de esta parte
Aprender a recorrer arreglos en EJS usando forEach y mostrar cada entrada con estilos de Bootstrap.
1️⃣ La sintaxis correcta en EJS para forEach
En tus im谩genes veo que est谩s usando <% entries.forEach(function(entry){ %> y <% }) %> para cerrar.
馃摉 Reglas importantes de EJS para forEach:
| Sintaxis | Funci贸n |
|---|---|
<% codigo %> | Ejecuta JavaScript (NO muestra nada) |
<%= variable %> | Muestra el valor en el HTML |
<% entries.forEach(...) { %> | Abre el bucle |
<% }) %> | Cierra el bucle |
2️⃣ El index.ejs completo (seg煤n tus im谩genes)
Basado en tus capturas, este es el c贸digo correcto:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title><%= title %></title>
<% include partials/head %>
</head>
<body class="container">
<% include partials/header %>
<% if(entries.length) { %>
<% entries.forEach(function(entry){ %>
<div class="panel panel-primary">
<div class="panel-heading">
<%= entry.title %>
<div class="pull-right">
<%= entry.published %>
</div>
</div>
<div class="panel-body">
<%= entry.content %>
</div>
</div>
<% }) %>
<% } else { %>
<p>No existen entradas</p>
<a href="/new-entry">¡Agrega una!</a>
<% } %>
</body>
</html>3️⃣ Explicaci贸n l铆nea por l铆nea del c贸digo
L铆nea 11: Verificar si hay entradas
<% if(entries.length) { %>entriesviene deapp.locals.entries(lo configuramos en routes/index.js)entries.lengthes 0 si no hay entradasSi hay entradas, ejecuta el c贸digo dentro del
if
L铆nea 12: Recorrer cada entrada con forEach
<% entries.forEach(function(entry){ %>forEaches un m茅todo de JavaScript para recorrer arreglosentryes cada elemento del arreglo (cada mensaje)El
<% ... %>ejecuta c贸digo pero no muestra nada en pantalla
L铆neas 13-20: Mostrar cada entrada
<div class="panel panel-primary">
<div class="panel-heading">
<%= entry.title %> <!-- Muestra el t铆tulo -->
<div class="pull-right">
<%= entry.published %> <!-- Muestra la fecha -->
</div>
</div>
<div class="panel-body">
<%= entry.content %> <!-- Muestra el contenido -->
</div>
</div>L铆nea 21: Cerrar el forEach
<% }) %>Este
%> )cierra el bucle que abrimos conforEach
L铆neas 22-25: Si NO hay entradas
<% } else { %>
<p>No existen entradas</p>
<a href="/new-entry">¡Agrega una!</a>
<% } %>4️⃣ Otra forma de escribir forEach (m谩s moderna)
EJS tambi茅n permite usar arrow functions (m谩s moderno):
<% entries.forEach(entry => { %>
<div class="panel panel-primary">
<div class="panel-heading">
<%= entry.title %>
</div>
<div class="panel-body">
<%= entry.content %>
</div>
</div>
<% }) %>5️⃣ Formato de fecha mejorado
La fecha entry.published es un objeto Date. Podemos formatearla mejor:
<div class="pull-right">
<%= entry.published.toLocaleDateString() %>
<!-- Muestra: 14/5/2024 -->
O con hora:
<%= entry.published.toLocaleString() %>
<!-- Muestra: 14/5/2024, 15:30:45 -->
</div>6️⃣ A帽adir un footer (opcional)
Si quieres agregar un footer como en tus im谩genes, crea views/partials/footer.ejs:
<!-- views/partials/footer.ejs -->
<footer class="text-center" style="margin-top: 50px; padding: 20px; border-top: 1px solid #ddd;">
<p>© 2024 - Mi GuestBook con Node.js y EJS</p>
</footer>Y luego en index.ejs (antes de </body>):
<% include partials/footer %>7️⃣ C贸digo completo de routes/index.js (recordatorio)
Aseg煤rate de que routes/index.js est茅 correcto:
module.exports = (app) => {
let entries = [];
app.locals.entries = entries;
app.get('/', (req, res) => {
res.render('index', {
title: 'Inicio'
});
});
app.get('/new-entry', (req, res) => {
res.render('new-entry', {
title: 'Nueva Entrada'
});
});
app.post('/new-entry', (req, res) => {
if (!req.body.title || !req.body.body) {
res.status(400).send('Entradas deben tener un t铆tulo y un cuerpo');
return;
}
let newEntry = {
title: req.body.title,
content: req.body.body,
published: new Date()
};
entries.push(newEntry);
res.redirect('/');
});
};8️⃣ Errores comunes y soluciones
Error 1: No se ven las entradas
<!-- ❌ MAL: El igual (=) hace que se muestre algo que no quieres -->
<%= entries.forEach(entry => { %>
<!-- ✅ BIEN: Sin igual, solo ejecuta el c贸digo -->
<% entries.forEach(entry => { %>Error 2: Olvidar cerrar el forEach
<!-- ❌ MAL: Falta cerrar el bucle -->
<% entries.forEach(entry => { %>
<%= entry.title %>
<!-- FALTA <% }) %> -->
<!-- ✅ BIEN: Siempre cerrar el bucle -->
<% entries.forEach(entry => { %>
<%= entry.title %>
<% }) %>Error 3: Confundir if con forEach
<!-- ❌ MAL: if no es para recorrer, solo para condicionar -->
<% if(entry in entries) { %> <!-- Esto no recorre nada -->
<!-- ✅ BIEN: if para condici贸n, forEach para recorrer -->
<% if(entries.length > 0) { %>
<% entries.forEach(entry => { %>
<%= entry.title %>
<% }) %>
<% } %>9️⃣ Comparativa: for vs forEach en EJS
| M茅todo | C贸digo | Cu谩ndo usar |
|---|---|---|
| for cl谩sico | <% for(let i=0; i<entries.length; i++) { %> | Cuando necesitas el 铆ndice |
| forEach | <% entries.forEach(entry => { %> | Cuando solo necesitas el valor |
| for...of | <% for(let entry of entries) { %> | Alternativa moderna |
Ejemplo con for cl谩sico:
<% for(let i = 0; i < entries.length; i++) { %>
<div class="panel panel-primary">
<div class="panel-heading">
#<%= i+1 %> - <%= entries[i].title %>
</div>
<div class="panel-body">
<%= entries[i].content %>
</div>
</div>
<% } %>馃敓 Probar la aplicaci贸n
Paso 1: Asegurar estructura de archivos
views/
├── partials/
│ ├── head.ejs
│ └── header.ejs
├── index.ejs (con el c贸digo de este tutorial)
└── new-entry.ejsPaso 2: Iniciar servidor
npm run devPaso 3: Probar el flujo completo
Entrar a
http://localhost:3000/→ Ve "No existen entradas"Click en "Write a GuestBook" o "/new-entry"
Agregar t铆tulo y contenido
Enviar
Ver la entrada mostrada con el panel de Bootstrap
馃摑 Resumen de sintaxis EJS para este tutorial
| Lo que quieres hacer | C贸digo EJS |
|---|---|
| Mostrar variable | <%= variable %> |
| Ejecutar JavaScript (if, for, forEach) | <% codigo %> |
| Abrir un bucle forEach | <% entries.forEach(entry => { %> |
| Cerrar un bucle forEach | <% }) %> |
| Condici贸n if | <% if(condicion) { %> ... <% } %> |
| Condici贸n if-else | <% if(condicion) { %> ... <% } else { %> ... <% } %> |
| Incluir otro archivo EJS | <% include partials/nombre %> |
✅ Verifica que todo funcione
Prueba 1: ¿Se ven los mensajes?
→ Deber铆as ver cada entrada dentro de un panel panel-primary
Prueba 2: ¿La fecha aparece?
→ Deber铆as ver la fecha y hora en la esquina superior derecha
Prueba 3: ¿Funciona cuando no hay entradas?
→ Deber铆as ver "No existen entradas" y un enlace para agregar
馃殌 Pr贸xima parte: Mejoras y persistencia
¿Quieres que continuemos con:
Parte 6: Guardar entradas en un archivo JSON (para no perder datos al reiniciar)
Parte 7: Agregar mensajes flash (notificaciones de "Guardado exitoso")
Parte 8: Editar y eliminar entradas
Comentarios
Publicar un comentario