CursosEmpresasBlogLiveConfPrecios

Filtrando películas por categoría

Clase 11 de 17 • Curso de API REST con Javascript: Ejemplos con APIs reales

Clase anteriorSiguiente clase

Contenido del curso

Presentación del proyecto: PlatziMovies
  • 1
    TheMovieDB: análisis de su API

    TheMovieDB: análisis de su API

    07:15
  • 2
    Bocetos en papel y diseño en Figma

    Bocetos en papel y diseño en Figma

    08:05
Configuración inicial y maquetación del proyecto
  • 3
    Configuración del entorno de desarrollo

    Configuración del entorno de desarrollo

    16:53
  • 4
    Maquetación del proyecto: HTML y CSS

    Maquetación del proyecto: HTML y CSS

    18:34
Consumiendo la API
  • 5
    Lista de películas en tendencia

    Lista de películas en tendencia

    16:41
  • 6
    Lista de categorías

    Lista de categorías

    10:32
  • 7
    Migración a Axios

    Migración a Axios

    07:18
Navegación
  • 8
    Location y hash navigation

    Location y hash navigation

    17:17
  • 9
    Mostrando y ocultando secciones

    Mostrando y ocultando secciones

    22:05
  • 10
    Error: carga duplicada de datos

    Error: carga duplicada de datos

    06:30
Views
  • 11
    Filtrando películas por categoría

    Filtrando películas por categoría

    21:38
  • 12
    Retos: scrollTop y DRY

    Retos: scrollTop y DRY

    11:13
  • 13
    Buscador de películas

    Buscador de películas

    11:10
  • 14
    Retos: historial de navegación y página de tendencias

    Retos: historial de navegación y página de tendencias

    06:19
  • 15
    Endpoint de detalles de una película

    Endpoint de detalles de una película

    18:55
  • 16
    Lista de películas recomendadas

    Lista de películas recomendadas

    07:36
Próximos pasos
  • 17
    Toma el Curso Profesional de Consumo de API REST con JavaScript

    Toma el Curso Profesional de Consumo de API REST con JavaScript

    02:19
    Juan Sebastian Espínola

    Juan Sebastian Espínola

    student•
    hace 4 años

    ¿Qué opinan de esta solución? .

      Federico Ivan Llano

      Federico Ivan Llano

      student•
      hace 4 años

      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

      Elber Liebermen

      student•
      hace 4 años

      Wow muy interesante tu solución, me gustó mucho 😃

    Andres Chavez

    Andres Chavez

    student•
    hace 4 años

    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:

    Sin título.png

    Pero pues lo podemos solucionar con un simple replace:p

    replace.png

      Juan Castro

      Juan Castro

      teacher•
      hace 4 años

      Buen 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

      Andres Chavez

      student•
      hace 4 años

      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:

      correcion.png
    Ramiro Godoy

    Ramiro Godoy

    student•
    hace 3 años

    Para que la página inicie arriba y no en el footer, agregar en la función categoriesPage() el siguiente código:

    window.scroll(0,0);
    Lautaro Strappazzon

    Lautaro Strappazzon

    student•
    hace 4 años

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

      Lautaro Strappazzon

      student•
      hace 4 años

      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

      Raycris Maldonado

      student•
      hace 3 años

      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

    fabio andres zamora osorio

    student•
    hace 3 años

    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

      Juan Castro

      teacher•
      hace 3 años

      Correcto!

    Jose Castillo

    Jose Castillo

    student•
    hace 3 años

    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

    Fernando Yutiz

    student•
    hace 3 años

    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

      VICTOR CAUDILLO

      student•
      hace 3 años

      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

    Donovan RM

    student•
    hace 3 años

    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

    Sabad Josue Perez Rodriguez

    student•
    hace 3 años

    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

      Daniela Stornelli

      student•
      hace 3 años

      me pasa que las tildes no las reconoce y me pone varios simbolos en su lugar

    Antonio Rafael González Ferrer

    Antonio Rafael González Ferrer

    student•
    hace 3 años

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

    ![](

    reto-renderMovies.png

    No logré lo del scroll 😫😭

    Pablo Humberto Arriola Agudelo

    Pablo Humberto Arriola Agudelo

    student•
    hace 3 años

    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

      Edgardo Andres Vargas Saenz

      student•
      hace 3 años

      Hola mioficinaglobal447, seria: https://api.themoviedb.org/3/discover/movie?api_key=<TU_API_KEY>&with_genres=<GENRES_ID>

      Pablo Humberto Arriola Agudelo

      Pablo Humberto Arriola Agudelo

      student•
      hace 3 años

      Edgardo, muchas gracias

    Miguel Enrique Velásquez Millán

    Miguel Enrique Velásquez Millán

    student•
    hace 3 años

    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

    Diego Eduardo Téllez Contreras

    student•
    hace 3 años

    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

    Omer José Hernández Ramones

    student•
    hace 3 años

    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

    Donovan RM

    student•
    hace 3 años

    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

    Yangetze González

    company_admin•
    hace 3 años

    Like si antes de llegar a esta clase ya habías desarrollado esta funcionalidad jajajaja.

    JOSE RANGEL

    JOSE RANGEL

    student•
    hace 3 años

    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

    Christian Velázquez

    student•
    hace 3 años

    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

    Jose Angel Morales Gonzalez

    student•
    hace 3 años

    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

    Eduardo Peña Ramos

    student•
    hace 3 años

    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:

    Screen Shot 2022-07-09 at 11.38.12 a.m..png

    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

Escuelas

  • Desarrollo Web
    • Fundamentos del Desarrollo Web Profesional
    • Diseño y Desarrollo Frontend
    • Desarrollo Frontend con JavaScript
    • Desarrollo Frontend con Vue.js
    • Desarrollo Frontend con Angular
    • Desarrollo Frontend con React.js
    • Desarrollo Backend con Node.js
    • Desarrollo Backend con Python
    • Desarrollo Backend con Java
    • Desarrollo Backend con PHP
    • Desarrollo Backend con Ruby
    • Bases de Datos para Web
    • Seguridad Web & API
    • Testing Automatizado y QA para Web
    • Arquitecturas Web Modernas y Escalabilidad
    • DevOps y Cloud para Desarrolladores Web
  • English Academy
    • Inglés Básico A1
    • Inglés Básico A2
    • Inglés Intermedio B1
    • Inglés Intermedio Alto B2
    • Inglés Avanzado C1
    • Inglés para Propósitos Específicos
    • Inglés de Negocios
  • Marketing Digital
    • Fundamentos de Marketing Digital
    • Marketing de Contenidos y Redacción Persuasiva
    • SEO y Posicionamiento Web
    • Social Media Marketing y Community Management
    • Publicidad Digital y Paid Media
    • Analítica Digital y Optimización (CRO)
    • Estrategia de Marketing y Growth
    • Marketing de Marca y Comunicación Estratégica
    • Marketing para E-commerce
    • Marketing B2B
    • Inteligencia Artificial Aplicada al Marketing
    • Automatización del Marketing
    • Marca Personal y Marketing Freelance
    • Ventas y Experiencia del Cliente
    • Creación de Contenido para Redes Sociales
  • Inteligencia Artificial y Data Science
    • Fundamentos de Data Science y AI
    • Análisis y Visualización de Datos
    • Machine Learning y Deep Learning
    • Data Engineer
    • Inteligencia Artificial para la Productividad
    • Desarrollo de Aplicaciones con IA
    • AI Software Engineer
  • Ciberseguridad
    • Fundamentos de Ciberseguridad
    • Hacking Ético y Pentesting (Red Team)
    • Análisis de Malware e Ingeniería Forense
    • Seguridad Defensiva y Cumplimiento (Blue Team)
    • Ciberseguridad Estratégica
  • Liderazgo y Habilidades Blandas
    • Fundamentos de Habilidades Profesionales
    • Liderazgo y Gestión de Equipos
    • Comunicación Avanzada y Oratoria
    • Negociación y Resolución de Conflictos
    • Inteligencia Emocional y Autogestión
    • Productividad y Herramientas Digitales
    • Gestión de Proyectos y Metodologías Ágiles
    • Desarrollo de Carrera y Marca Personal
    • Diversidad, Inclusión y Entorno Laboral Saludable
    • Filosofía y Estrategia para Líderes
  • Diseño de Producto y UX
    • Fundamentos de Diseño UX/UI
    • Investigación de Usuarios (UX Research)
    • Arquitectura de Información y Usabilidad
    • Diseño de Interfaces y Prototipado (UI Design)
    • Sistemas de Diseño y DesignOps
    • Redacción UX (UX Writing)
    • Creatividad e Innovación en Diseño
    • Diseño Accesible e Inclusivo
    • Diseño Asistido por Inteligencia Artificial
    • Gestión de Producto y Liderazgo en Diseño
    • Diseño de Interacciones Emergentes (VUI/VR)
    • Desarrollo Web para Diseñadores
    • Diseño y Prototipado No-Code
  • Contenido Audiovisual
    • Fundamentos de Producción Audiovisual
    • Producción de Video para Plataformas Digitales
    • Producción de Audio y Podcast
    • Fotografía y Diseño Gráfico para Contenido Digital
    • Motion Graphics y Animación
    • Contenido Interactivo y Realidad Aumentada
    • Estrategia, Marketing y Monetización de Contenidos
  • Desarrollo Móvil
    • Fundamentos de Desarrollo Móvil
    • Desarrollo Nativo Android con Kotlin
    • Desarrollo Nativo iOS con Swift
    • Desarrollo Multiplataforma con React Native
    • Desarrollo Multiplataforma con Flutter
    • Arquitectura y Patrones de Diseño Móvil
    • Integración de APIs y Persistencia Móvil
    • Testing y Despliegue en Móvil
    • Diseño UX/UI para Móviles
  • Diseño Gráfico y Arte Digital
    • Fundamentos del Diseño Gráfico y Digital
    • Diseño de Identidad Visual y Branding
    • Ilustración Digital y Arte Conceptual
    • Diseño Editorial y de Empaques
    • Motion Graphics y Animación 3D
    • Diseño Gráfico Asistido por Inteligencia Artificial
    • Creatividad e Innovación en Diseño
  • Programación
    • Fundamentos de Programación e Ingeniería de Software
    • Herramientas de IA para el trabajo
    • Matemáticas para Programación
    • Programación con Python
    • Programación con JavaScript
    • Programación con TypeScript
    • Programación Orientada a Objetos con Java
    • Desarrollo con C# y .NET
    • Programación con PHP
    • Programación con Go y Rust
    • Programación Móvil con Swift y Kotlin
    • Programación con C y C++
    • Administración Básica de Servidores Linux
  • Negocios
    • Fundamentos de Negocios y Emprendimiento
    • Estrategia y Crecimiento Empresarial
    • Finanzas Personales y Corporativas
    • Inversión en Mercados Financieros
    • Ventas, CRM y Experiencia del Cliente
    • Operaciones, Logística y E-commerce
    • Gestión de Proyectos y Metodologías Ágiles
    • Aspectos Legales y Cumplimiento
    • Habilidades Directivas y Crecimiento Profesional
    • Diversidad e Inclusión en el Entorno Laboral
    • Herramientas Digitales y Automatización para Negocios
  • Blockchain y Web3
    • Fundamentos de Blockchain y Web3
    • Desarrollo de Smart Contracts y dApps
    • Finanzas Descentralizadas (DeFi)
    • NFTs y Economía de Creadores
    • Seguridad Blockchain
    • Ecosistemas Blockchain Alternativos (No-EVM)
    • Producto, Marketing y Legal en Web3
  • Recursos Humanos
    • Fundamentos y Cultura Organizacional en RRHH
    • Atracción y Selección de Talento
    • Cultura y Employee Experience
    • Gestión y Desarrollo de Talento
    • Desarrollo y Evaluación de Liderazgo
    • Diversidad, Equidad e Inclusión
    • AI y Automatización en Recursos Humanos
    • Tecnología y Automatización en RRHH
  • Finanzas e Inversiones
    • Fundamentos de Finanzas Personales y Corporativas
    • Análisis y Valoración Financiera
    • Inversión y Mercados de Capitales
    • Finanzas Descentralizadas (DeFi) y Criptoactivos
    • Finanzas y Estrategia para Startups
    • Inteligencia Artificial Aplicada a Finanzas
    • Domina Excel
    • Financial Analyst
    • Conseguir trabajo en Finanzas e Inversiones
  • Startups
    • Fundamentos y Validación de Ideas
    • Estrategia de Negocio y Product-Market Fit
    • Desarrollo de Producto y Operaciones Lean
    • Finanzas, Legal y Fundraising
    • Marketing, Ventas y Growth para Startups
    • Cultura, Talento y Liderazgo
    • Finanzas y Operaciones en Ecommerce
    • Startups Web3 y Blockchain
    • Startups con Impacto Social
    • Expansión y Ecosistema Startup
  • Cloud Computing y DevOps
    • Fundamentos de Cloud y DevOps
    • Administración de Servidores Linux
    • Contenerización y Orquestación
    • Infraestructura como Código (IaC) y CI/CD
    • Amazon Web Services
    • Microsoft Azure
    • Serverless y Observabilidad
    • Certificaciones Cloud (Preparación)
    • Plataforma Cloud GCP

Platzi y comunidad

  • Platzi Business
  • Live Classes
  • Lanzamientos
  • Executive Program
  • Trabaja con nosotros
  • Podcast

Recursos

  • Manual de Marca

Soporte

  • Preguntas Frecuentes
  • Contáctanos

Legal

  • Términos y Condiciones
  • Privacidad
  • Tyc promociones
Reconocimientos
Reconocimientos
Logo reconocimientoTop 40 Mejores EdTech del mundo · 2024
Logo reconocimientoPrimera Startup Latina admitida en YC · 2014
Logo reconocimientoPrimera Startup EdTech · 2018
Logo reconocimientoCEO Ganador Medalla por la Educación T4 & HP · 2024
Logo reconocimientoCEO Mejor Emprendedor del año · 2024
De LATAM conpara el mundo
YoutubeInstagramLinkedInTikTokFacebookX (Twitter)Threads