skip to Main Content

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);
  }
});

});

2

Answers


  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?

    Login or Signup to reply.
  2. 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>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search