Reputation: 1
DOM does not render the info I pick from the API jsonplaceholder. Just want to render some authors and abstracts.
This is my HTML code, and JS:
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Blog - Lista de Comentarios</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.flex {
display: flex;
flex-wrap: wrap;
}
.flex article {
width: calc(50% - 20px);
margin: 10px;
padding: 10px;
border: 2px solid black;
}
.flex article:nth-child(even)
{
background-color: #f0f0f0;
}
select {
border: 2px solid tomato;
width: 80%;
padding: 20px;
margin: 20px auto 0px auto;
display: block;
font-size: 150%;
}
hr {
margin: 20px;
}
</style>
</head>
<body>
<header>
<select id="selectAutor">
<option value="" selected>Selecciona un autor</option>
<option value="1">Autor 1</option>
<option value="2">Autor 2</option>
<option value="3">Autor 3</option>
<!-- Añadir más opciones según sea necesario -->
</select>
<hr>
</header>
<section id="comentarios" class="flex">
<!-- esta es la superficie iterable que hay que repetir por cada comentario -->
<article>
<h3>Nombre del autor</h3>
<p>Email: [email protected]</p>
<p>Comentario:</p>
<p>Texto del comentario</p>
</article>
</section>
<script src="script.js"></script>
</body>
</html>
document.addEventListener('DOMContentLoaded', () => {
// Función para obtener los comentarios de la API REST
async function obtenerComentarios() {
const url = '...URL...jsonplaceholder...';
try {
const response = await fetch(url);
const comentarios = await response.json();
return comentarios;
} catch (error) {
console.error('Error al obtener los comentarios:', error);
throw new Error('Error al obtener los comentarios');
}
}
// Función para mostrar los comentarios de un autor seleccionado
async function mostrarComentariosPorAutor(idAutor) {
console.log('ID del autor seleccionado:', idAutor);
try {
// Obtener todos los comentarios
const comentarios = await obtenerComentarios();
console.log('Comentarios obtenidos:', comentarios);
// Filtrar los comentarios del autor seleccionado
const comentariosAutor = comentarios.filter(comentario => comentario.userId == idAutor);
console.log('Comentarios del autor seleccionado:', comentariosAutor);
// Seleccionar el contenedor de comentarios en el DOM
const contenedorComentarios = document.getElementById('comentarios');
contenedorComentarios.innerHTML = '';
// Mostrar cada comentario del autor seleccionado en el DOM
comentariosAutor.forEach(comentario => {
const article = document.createElement('article');
article.innerHTML = `
<h3>Nombre del autor: ${comentario.name}</h3>
<p>Email: ${comentario.email}</p>
<p>Comentario:</p>
<p>${comentario.body}</p>
`;
contenedorComentarios.appendChild(article);
});
} catch (error) {
console.error('Error al mostrar los comentarios:', error);
}
}
// Manejar el evento de cambio en el selector de autor
document.getElementById('selectAutor').addEventListener('change', event => {
console.log('Evento de cambio detectado');
const idAutor = parseInt(event.target.value);
console.log('ID del autor seleccionado:', idAutor);
if (idAutor) {
mostrarComentariosPorAutor(idAutor);
}
});
});
Upvotes: 0
Views: 217
Reputation: 28206
I assume that OP was referring to the resource https://jsonplaceholder.typicode.com and therefore I prepared the following snippet to collect comments to posts a certain user (=author) has committed.
Maybe this is was OP wanted? In any case, there are a few patterns in here that might be helpful otherwise.
// if you place this script tag UNDER your body
// you will not need to use the DOMContentLoaded event
// and you can set up some global constants
const [autsel, cmtdisp] = ["selectAutor", "comentarios"].map(id => document.getElementById(id));
// asynchrounous IIFE: we are doing all the asynchronous stuff in here
(async function() {
const url = 'https://jsonplaceholder.typicode.com/';
try {
// get users and comments:
const [users, comments] = await Promise.all(["users", "comments"].map(v => fetch(url + v).then(r => r.json())));
// comments are related to postIds and these are related to users (authors)
// if you want to have comments per author your would need a two step lookup process.
// Luckily the data in JSON placeholder follows a simple pattern:
// userId = 1+Math.floor((postId-1)/10)
// We can use this to reorganize our comments:
const cmts = comments.reduce((a, c) => {
(a[1 + Math.floor((c.postId - 1) / 10)] ??= []).push(c);
return a;
}, {});
autsel.innerHTML = users.map(u => `<option value="${u.id}">${u.name}</option>`).join("");
autsel.addEventListener("change", showComments(cmts));
showComments(cmts)({target:{value:1}}) // show comments for first author ...
} catch (error) {
console.error('Error getting users and comments:', error);
throw new Error('Error getting users and comments');
}
})();
function showComments(cmtsObj) {
return function(ev) {
const id = ev.target.value;
cmtdisp.innerHTML = cmtsObj[id].map(c => `<article>
<h3>${c.name}</h3>
<p>Email: ${c.email}</p>
<p>Comentario:</p>
<p>${c.body}</p>
</article>`).join("\n")
}
}
article {
margin: 4px;
padding: 4px;
border: solid grey 1px
}
<header>
<select id="selectAutor">
</select>
<hr>
</header>
<section id="comentarios" class="flex">
</section>
Upvotes: 0
Reputation: 1
I translated your code to english and added some demo JSON. it works:
https://jsfiddle.net/gtpo4j3m/
so I guess you should check your JSON response by doing something like:
const response = await fetch(url);
const comentarios = await response.json();
console.log('comentarios', comentarios);
The response should be similar to the getComments() function in the jsfiddle. What does it say?
Upvotes: 0