Contenido del curso
Optimización de imágenes
Paginación
Almacenamiento local
Bonus
Próximos pasos
Gestión de Películas Favoritas con Local Storage en JavaScript
Resumen
Mostrar la lista de películas favoritas en una app con JavaScript implica leer el objeto guardado en localStorage, convertirlo en array y renderizarlo en el DOM. Esta guía explica cómo lograrlo, sincronizar el estado visual de los botones de like y resolver los errores de navegación que aparecen cuando agregas una nueva sección al HTML.
Cómo leo las películas favoritas desde localStorage
La idea es replicar la lógica de funciones como getTrendingMovies o getMoviesBySearch, pero en vez de consumir una API, consumimos localStorage.
Para empezar, creas una función getLikedMovies que invoca a la función likedMoviesList, la cual hace JSON.parse de lo que viene guardado y devuelve un objeto con cada película indexada por su id.
¿Cómo convierto un objeto de localStorage en un array? Usa
Object.values(miObjeto). Ese método devuelve un array con todos los valores del objeto, ignorando las llaves, listo para iterarlo o pasarlo a una función de renderizado.
Una vez tienes el array, lo pasas a createMovies junto con el contenedor, el flag de lazy loading y el flag para limpiar el HTML previo:
- El array de películas viene de
Object.values(likedMovies). - El contenedor es el nodo
likedMoviesListArticleseleccionado condocument.querySelector. - Lazy loading en
truepor si la lista crece. - Limpieza del contenedor en
truepara evitar duplicados al recargar.
Un detalle fácil de pasar por alto: al definir el selector en el archivo de nodos, el querySelector necesita el punto inicial para clases (.liked-movies-list) o el # para IDs. Sin ese punto, recibes el clásico error Cannot read properties of null (reading 'innerHTML').
Por qué los botones de like se ven desincronizados al recargar
Cuando recargas la página, los botones de corazón pierden la clase movie-button-liked porque el DOM se reconstruye desde cero. Aunque la información persiste en localStorage, la UI no la refleja hasta que la consultas explícitamente al pintar cada tarjeta.
Cómo sincronizo el estado visual del botón con localStorage
Dentro de la función createMovies, justo donde defines el botón de like, agregas un condicional que pregunta si el id de esa película existe en el objeto que devuelve likedMovieList():
javascript if (likedMovieList()[movie.id]) { movieBtn.classList.add('movie-button-liked'); }
Aquí no usas toggle, porque toggle invierte el estado. Lo que necesitas es solo añadir la clase cuando la película ya esté guardada. El toggle se queda únicamente para el event listener del clic, donde sí queremos alternar.
¿Qué hace Object.values en JavaScript? Recibe un objeto y devuelve un array con todos sus valores, en el orden en que fueron declarados. Es la forma más limpia de iterar valores de un objeto sin tocar las claves.
Cómo arreglo la navegación entre secciones
Al agregar la sección de favoritos al HTML, esta aparece en todas las rutas porque nunca le aplicas la clase inactive. La solución vive en navigation.js.
Primero, declaras el nodo en el archivo de selectores:
likedMoviesSectionapunta al elemento con idliked.- Lo importas en
navigation.jsjunto con el resto. - Replicas la misma lógica de
addyremoveque ya usas paratrendingPreviewSection.
La regla práctica: cada vez que trendingPreviewSection recibe classList.remove('inactive') (en homePage), también se lo quitas a likedMoviesSection. Y cada vez que se lo agregas en categoriesPage, movieDetailsPage, searchPage o trendsPage, repites el add('inactive') para favoritos.
Con eso, la sección de películas favoritas solo aparece en el home y desaparece en categorías, búsqueda, tendencias y detalle de película.
Cómo escucho cambios de localStorage en tiempo real
Queda un detalle: si das like desde la página de tendencias sin navegar a otra ruta, la lista de favoritos del home no se actualiza hasta que recargas o cambias de sección. La razón es que getLikedMovies solo se ejecuta cuando se llama a homePage.
La solución es escuchar el evento storage del objeto window. Funciona como cualquier otro event listener:
javascript window.addEventListener('storage', getLikedMovies);
Cada vez que algo cambie en localStorage, el evento se dispara y vuelves a renderizar la lista. La documentación de MDN sobre Storage Event es la referencia recomendada para profundizar.
¿Cuándo se dispara el evento storage en JavaScript? Se dispara cuando otro documento del mismo origen modifica localStorage o sessionStorage. En la misma pestaña que hace el cambio puede no dispararse, así que a veces conviene emitir un evento personalizado tras escribir.
Qué aprendiste sobre persistencia y DOM en esta práctica
Resolver este flujo te entrena en habilidades concretas:
- Manipulación del DOM con
querySelectory respeto a la sintaxis de selectores CSS. - Persistencia con
localStorageusandoJSON.parseyJSON.stringify. - Conversión de objetos a arrays con
Object.valuespara reutilizar funciones de renderizado. - Control de visibilidad de secciones mediante una clase
inactivey event listeners de navegación. - Sincronización de estado visual con datos persistidos al cargar la página.
El reto abierto es claro: implementa el event listener de storage para que la lista de favoritos se actualice sin recargar ni navegar. Cuéntame en los comentarios qué nombre le habrías puesto al nodo likedMoviesListArticle y cómo resolviste la actualización en tiempo real.