Juan Sebastian Espínola
¿Qué opinan de esta solución? .
Federico Ivan Llano
Muy buena tu solucion, y yo pensando en que iba a necesitar usar clases, pero claro con la funcion y enviando parametros se soluciona. 👏
Elber Liebermen
Wow muy interesante tu solución, me gustó mucho 😃
Andres Chavez
No sé si más adelante lo corrige el profe, pero al momento de entrar en una categoría que contiene un espacio en su título nos encontramos esto:
Pero pues lo podemos solucionar con un simple replace:p
Juan Castro
ProfesorBuen ojo ahí. ¿Sabes por qué aparece ese %20 en vez de un espacio? ¿Habrá alguna otra conversión o caso raro que debamos evaluar para solucionar?
Andres Chavez
Lautaro Strappazzon
Lautaro Strappazzon
POSTER_300W_URL simplemente es una variable en la que guardé la url que nos permite imprimir los pósters con una ancho de 300:
const POSTER_300W_URL = 'https://image.tmdb.org/t/p/w300';
Raycris Maldonado
Muy buen aporte, tambien lo pense de esa manera, sacar una funcion a parte. me resulto de mucha ayuda lo del scroll
fabio andres zamora osorio
Segun lo que entendi en esta clase el hash no solo sirve para la navegacion entre paginas sino que tambien sirve para almacenar en dicho hash datos traidos de un endpoint de la api, de esta forma al leer el hash se obtiene el dato requerido para hacer peticiones a otros endpoints de la api. ¿estoy en lo correcto o no?
Juan Castro
ProfesorCorrecto!
Investigue el scrollTo(cord-x, cord-y);
con este método solucionamos el problema del scroll que aparece hasta abajo, solo debemos insertar el código en la función de navegación de categoriesPage:
window.scrollTo(0,0);
de este modo se ubicara al inicio de la pagina.
Hay otro detalle que cuando hacemos un refresh (f5), o usamos el botón de ir a atras en el navegador, si tenemos el scroll hasta abajo este no cambia su posición.
Un comportamiento optimo seria que si actualizamos la pagina o le damos hacia atras o adelante, este se ubique al inicio de la pagina, para solucionar esto también podemos usar el scrollTo anclado a un evento.
window.onbeforeunload = () => { scrollTo(0,0); }
Este bloque de código, va en el main.js.. ahora cada vez que actualicemos o le demos hacia atrás, la vista de la pagina se ubicara desde el inicio.
Fernando Yutiz
Se me ocurrió como solución alternativa para mostrar la categoría al usuario, colocarla como parte del titulo
document.title=`PlatziMovies ${category.name}`;
Que les parece?
VICTOR CAUDILLO
Me parece una mejor opción sobre todo pq al tomar el valor de la url se podria alterar o mostrar signos raros, buena idea!!
Donovan RM
Para evitar que Ponga en el Title los caracteres codificados % de espacio y acentuación se puede usar el:
decodeURIComponent()
en el innerHTML es decir: en el navigation.js
const [categ, categoryData] = location.hash.split('=');// ['#category','id-name'] const [categoryId, categoryName] = categoryData.split('-'); headerCategoryTitle.innerHTML= decodeURIComponent(categoryName); getMoviesByCategory(categoryId);
Sabad Josue Perez Rodriguez
Para poner en español las respuestas de la api (Categorías y algunos posters de Series y Películas) usando Axios, definimos en los parametros de la solicitud el parametro 'language' : 'es'. .
const api = axios.create({ baseURL: 'https://api.themoviedb.org/3', headers: { 'Content-Type': 'application/json;charset=utf-8' }, params:{ 'api_key': API_KEY, 'language': 'es' //para que las categorias lleguen en español } })
Daniela Stornelli
me pasa que las tildes no las reconoce y me pone varios simbolos en su lugar
Antonio Rafael González Ferrer
Pablo Humberto Arriola Agudelo
Alguien puede pasarme la url filtrada por alguna categoria, asi:
htt.. api. themoviedb. org/ 3/ trending/ movie/ discover/ movie/ ......... hasta completarla Gracias.
Edgardo Andres Vargas Saenz
Hola mioficinaglobal447, seria: https://api.themoviedb.org/3/discover/movie?api_key=<TU_API_KEY>&with_genres=<GENRES_ID>
Pablo Humberto Arriola Agudelo
Edgardo, muchas gracias
Miguel Enrique Velásquez Millán
Supongo que justo ese método de "colocar el id seguido de un - para luego colocar el nombre de la sección" es lo que utilizan aquí en platzi, je je. De ahí que las url de los cursos y las clases sean cosas como "/platzi.com/clases/2986-api-practico/48456-filtrando-peliculas-por-categoria/".
Diego Eduardo Téllez Contreras
Dejo esto por acá porque seguro que a alguien le va a servir... "Genre" es una de esas palabras en inglés que tiene una pronunciación muy rara... viene siendo algo como: "shonra".
En google translate pueden darle al iconito de sonido para escuchar como se dice:
https://translate.google.com/?hl=es&sl=en&tl=es&text=genre&op=translate
Omer José Hernández Ramones
Para el reto les dejo la función que usé, por cursos anteriores y documentación que he leído, decían que no se recomienda usar innerHTML para manejo del DOM por cuestiones de seguridad y también que es menos eficiente, en mi caso hago uso de la función replaceChildren() que en caso de no pasarle ningún parámetro elimina los hijos de un contenedor
function createMovies(movies, container){ let moviesList = []; container.replaceChildren(); movies.forEach( movie => { const movieContainer = document.createElement('div'); const movieImg = document.createElement('img'); movieContainer.classList.add('movie-container'); movieImg.classList.add('movie-img'); movieImg.setAttribute('alt', movie.title); movieImg.setAttribute('src', 'https://image.tmdb.org/t/p/w300/'+movie.poster_path); movieContainer.append(movieImg); moviesList.push(movieContainer); }); container.append(...moviesList); }
Donovan RM
Y para los que han usado la funcion insertAdjacentHTML en el main. esta es una propuesta que funciona para enviar el hash del evento click:
categories.forEach(category => { const categoryId = category.id; const categoryName = category.name; //const encodedCategoryName = encodeURIComponent(categoryName); const hash = `#category=${categoryId}-${categoryName}`; categoriesPreviewList.insertAdjacentHTML('beforeend', ` <div class="category-container"> <h3 id="id${categoryId}" class="category-title">${categoryName}</h4> </div> `); const categoryTitle = document.querySelector(`#id${categoryId}`); categoryTitle.addEventListener('click', () => { location.hash = hash; }); });
Yangetze González
Company_adminLike si antes de llegar a esta clase ya habías desarrollado esta funcionalidad jajajaja.
JOSE RANGEL
Para evitarnos escribir el mismo código que renderice cada película (ya sea en el home o en la lista de películas por categoría), podríamos crear una función al cual se le pase dos parámetros, la data y el nodo donde se deben 'pintar'. . Puede ser algo más o menos así: .
function renderMoviesHtml(data, node){ data.forEach(movie => { const movieContainer = document.createElement('div'); movieContainer.classList.add('movie-container'); const movieImg = document.createElement('img'); movieImg.classList.add('movie-img'); movieImg.setAttribute('alt', movie.title); movieImg.setAttribute('src', `https://image.tmdb.org/t/p/w300/${movie.poster_path}`); movieContainer.appendChild(movieImg); node.appendChild(movieContainer) }); }
. Luego sería llamar esta función pasándole los respectivos argumentos y ahorramos varias líneas de código.
Christian Velázquez
Una clse genial!! Creo que, para los que van comenzando pueden volver a repasae éste curso (proyecto) para un curso como "webpack". Además, como el de "Single Page Application".
Jose Angel Morales Gonzalez
Esta era mi solución:
const index = window.location.hash.indexOf('=') const index2 = window.location.hash.indexOf('-') const query = window.location.hash.substring(index + 1, index2)
es muy forzada
Eduardo Peña Ramos
Solución al reto de cargar la página desde el top: basta con poner esta línea de código en nuestra función:
window.scrollTo(0, 0);
Ejemplo:
Y para el que quiera profundizar más, esta es su documentación: https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollTop
Saludos! :D
Encontré que usualmente un % seguido de dos números quieren decir que un string fue codificado para formar parte de un URI, por cuestiones de evitar caracteres raros.
Se recomienda usar:
Para solucionar el segundo reto (ahorrarnos líneas de código para una funcionalidad que se repite), lo que hice fue hacer una función llamada printMoviePosters, que recibe como paråmetros el objeto movies, y la sección en la que corresponde. Luego, cada función que la necesite la llamará, pasándole los parámetros correspondientes:
const printMoviePosters = (movies, section) => { section.innerHTML = ""; movies.forEach(movie => { const movieContainer = document.createElement('div'); movieContainer.classList.add('movie-container'); const movieImg = document.createElement('img'); movieImg.classList.add('movie-img'); movieImg.setAttribute('alt', movie.title); movieImg.setAttribute( 'src', `${POSTER_300W_URL}${movie.poster_path}` ); movieContainer.appendChild(movieImg); section.appendChild(movieContainer); }); } const getTrendingMoviesPreview = async () => { const { data } = await api('/trending/movie/day'); const movies = data.results; printMoviePosters(movies, trendingMoviesPreviewList); } const getMoviesByCategory = async (categoryId) => { const { data } = await api('/discover/movie', { params: { with_genres: categoryId, }, } ); const movies = data.results; printMoviePosters(movies, genericSection); }
En cuanto al reto del problema del scroll, creo haberlo solucionado agregando el scrollTo(0,0) en la función que se dispara al hacer click en el botón categoryTitle:
categoryTitle.addEventListener('click', () => { location.hash = `#category=${category.id}-${category.name}`; window.scrollTo(0, 0); })
Esta fue mi solución para re utilizar el código de las películas:
async function getTrendingMoviesPreview() { body.scrollTop = 0 const { data } = await api(URL_TrendingMovies) const movies = data.results trendingMoviesPreviewList.innerHTML = '' renderMovies(trendingMoviesPreviewList, movies) } async function getMoviesByCategory(id) { const { data } = await api(URL_DiscoverMovie,{ params: { with_genres: id } }) const movies = data.results genericSection.innerHTML = '' renderMovies(genericSection, movies) } function renderMovies(mainSection, movies) { movies.forEach(movie => { const movieContainer = document.createElement('div') movieContainer.classList.add('movie-container') const movieImg = document.createElement('img') movieImg.classList.add('movie-img') movieImg.setAttribute('alt', movie.title) movieImg.setAttribute('src', `https://image.tmdb.org/t/p/w300${movie.poster_path}`) movieContainer.appendChild(movieImg) mainSection.appendChild(movieContainer) }) }
También corregí el detalle de los espacios en el títulos de las categorías:
function categoriesPage() { // console.log('Category!!') headerSection.classList.remove('header-container--long') headerSection.style.background = '' arrowBtn.classList.remove('inactive') arrowBtn.classList.remove('header-arrow--white') headerTitle.classList.add('inactive') headerCategoryTitle.classList.remove('inactive') searchForm.classList.add('inactive') trendingPreviewSection.classList.add('inactive') categoriesPreviewSection.classList.add('inactive') genericSection.classList.remove('inactive') movieDetailSection.classList.add('inactive') const [_ , categoryData] = location.hash.split('=') const [categoryId, categoryName] = categoryData.split('-') headerCategoryTitle.innerText = categoryName.replace('_', ' ') getMoviesByCategory(categoryId) }
![](
No logré lo del scroll 😫😭