Dario Paladines
Raycris Maldonado
Luis Alejandro Vera Hernandez
Jonathan Alfonso
Juan Castro
ProfesorWalter Llanos
Enrique Aguilera
Víctor Fabián Morales Rodríguez
Lautaro Strappazzon
Juan Castro
ProfesorDaniel González
Leonard Sumoza
fabio andres zamora osorio
Juan Castro
ProfesorFernando Yutiz
Ricardo Alfonso Chavez Vilcapoma
Juan Cortez
Alonso Chaves
Johnner Alexander Gambacica Ortiz
Leonardo Jaimovich
Sergio Javier Lopez Olivera
Luis Paredes
Marcelo Jorge Bellizia
Marcelo Jorge Bellizia
CRISTIAN DARIO AGUDELO PORRAS
Jose Ever Muñoz Muñoz
Daniel Rodriguez
Axel Enrique Galeed Gutierrez
Manuel Araujo
Creo que la solución más fácil que pude encontrar es simplemente ejecutar la función getLikedMovies() en el listener, literalmente solo agregue esa linea y por el momento funciona en todas las paginas que se agrega la película sin necesidad de recargar
movieBtn.addEventListener('click', ()=>{ movieBtn.classList.toggle('btnMovie--liked') likeMovie(movie); getLikedMovies() //única linea agregada })
Yo tambien vi esa solucion!
Super!
Actualización de favoritos . Intente hacerla con el Windows.storage.event pero no pude. Leí la documentación y al parecer solo funciona cuando el localStorage se modifica desde otro documento. Hasta hay una nota al comienzo que dice: .
Note: This won’t work on the same page that is making the changes — it is really a way for other pages on the domain using the storage to sync any changes that are made. Pages on other domains can’t access the same storage objects.
. Quisiera saber si estoy en lo correcto y entendí bien, o de lo contrario como podría realizarla.
Yo lo solucioné de una forma bastante sencilla, haciendo recargar el home cuando se realiza un cambio estando en el mismo. Así como está configurado el cache, el cambio es instantáneo con cualquier velocidad de internet. Antes intenté hacerla llamando a la funcion getLikedMovies() en vez de al homePage(), pero al quitar una película de favoritos sigue manteniendo el estilo en el resto de las secciones.
function likeMovie(movie) { ... if (location.hash == ''){ homePage(); } }
Muy bien desarrollado este ejercicio :clap:
Tuve que complementar tu condicional así:
if (location.hash.startsWith('#home') || !location.hash) { homePage(); }
Para que en caso que esté en #home luego de ir a otra sección y regresar todavía funcione.
Ya que no me funcionó el window.storage, lo que hice fue volver a llamar a las funciones getTrendingMoviesPreview() y getLikedMovies() al final de la funcion likeMovies() y de momento funciona bien
function likeMovies(movie) { const likedMovies = likesMoviesList() if(likedMovies[movie.id]) { likedMovies[movie.id] = undefined } else { likedMovies[movie.id] = movie } localStorage.setItem("liked-movies", JSON.stringify(likedMovies)) getTrendingMoviesPreview() getLikedMovies() }
jeje yo hice exactamente lo mismo :)
Basándome en el excelente aporte previo de Jonathan Alfonso, me dí cuenta que si hacía scroll horizontal en TrendingPreview y le daba like a una película, al recargárseme completamente el home el scroll horizontal volvía al comienzo. Siento que ++esto puede afectar un poco la Experiencia del Usuario++, por lo que me pareció mejor que la función likeMovie llame a getTrendingPreviewMovie y a getLikedMovies:
function likeMovie(movie) { ... if (location.hash == ''){ getLikedMovies(); getTrendingMoviesPreview(); } }
Estas dos funciones limpian sus contenedores de scroll para que no se dupliquen las películas:
const getLikedMovies = () => { likedMoviesScroll.innerHTML = ""; let likedMovies = Object.values(likedMovieList()); printMoviePosters(likedMovies, likedMoviesScroll, true); } const getTrendingMoviesPreview = async () => { const { data } = await api('/trending/movie/day'); const movies = data.results; trendingMoviesPreviewList.innerHTML = ""; printMoviePosters(movies, trendingMoviesPreviewList, true); }
:100:
Si quieren ocultar toda la sección de favoritos cuando no hayan películas seleccionadas, se puede agregar la clase inactive dentro de la función getLikedMovies() de la siguiente forma:
function getLikedMovies() { const likedMovies = likedMovieList(); const moviesArray = Object.values(likedMovies); likedMoviesListArticle.innerHTML = ''; !moviesArray.length && likedMoviesSection.classList.add('inactive'); createMovies(moviesArray, likedMoviesListArticle); }
Saludos, por mi parte solo inserte la función homepage() en el evento de hacer click en el botón de me gusta de, así cada que se cliquee para gustar o no una película la pagina inicial se recargara
<code> movieBtn.addEventListener('click', () => { movieBtn.classList.toggle('movie-btn--liked'); likeMovie(movie); homePage(); });
este código se encuentra dentro de la función createMovies()
Como se llama esta forma de hacer condicionales que implemento el profesor para buscar informacion y estudiarla:
likedMoviesList()[readMovies.id] && movieBtn.classList.add('movie-btn--liked')
la verdad no la conocia yo solo conocia los condicionales con if/else o con el operador ternario
Se llama Logical AND: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Logical_AND
Mi solución fue tan sencilla, que aun sigo mirando si cometí algun error jaja Solo agregue un llamado a homepage() desde al final del evento click del botón movieBtn.
Llegaste aquí
ERES UN CRACK
Siguiente paso:
REACT O ALGÚN FRAMEWORK
Mi solución fue llamar a homePage para que refresque la página. No sé si está bien, pero fue una solución rápida. En este caso, item reemplaza a movie.
movieBtn.addEventListener('click',()=>{ movieBtn.classList.toggle('movie-btn--liked'); likeMovie(item); homePage(); })
Yo intenté hacer algo parecido pero con window.addEventListener('click', navigator, false) en navigation.js
Pero tiene el inconveniente de que si se busca una pelicula muy abajo, al darle click al favorito se recarga la pagina y hay que volver a buscar por donde iba uno. Funciona, pero es mejor solución de el estudiante Dario Paladines (El aporte con mas likes 40+) para que no haya necesidad de recargar y que el usuario se pierda. En mi opinión.
Un push a la lista de películas favoritas
yo llame en la función q actualiza el storage a las funciones q refrescan tanto las trending movies preview como las peliculas likeadas. Anda perfecto y actualiza todos los botones de like, aparecen y desaparecen de la lista de likeadas,etc. Voy a probar con el evento del localStorage, supongo q es mucho mas elegante!
Esta fue mi solución, ejecutar la función likedMovies y recorrer el arreglo resultante verificando si la película en cuestión tenía el mismo ID de la película que se estaba renderizando en ese momento en la función renderMovie (createMovie): .
const moviesArr = Object.values(likedMoviesList()); if(moviesArr){ moviesArr.forEach(m => { if(m.id == movie.id){ movieBtn.classList.add('movie-btn--liked'); } else { movieBtn.classList.add('movie-btn'); } movieBtn.addEventListener('click', () => { movieBtn.classList.toggle('movie-btn--liked'); likeMovie(movie) //function to add movies to localStorage and to the favorites section }) }) } movieContainer.append(movieImage); movieContainer.append(movieBtn);
la solucion a la que llegue es sencilla pero me tomo como una hora llegar a ella para enviar los datos de forma correcta
function getFavoriteMovies () { const movies = likedMovieList() const moviesArray = Object.values(movies) console.log(Object.values(movies)) if (movies != {}) { createMovieList(moviesArray, favoriteMovieList, { lazyLoad : true , clean : true } ) } }
Yo intente hacer esto antes de verlo y lo único que hice distinto es la parte de darle el estilo o no. Por si a alguien le sirve mi lógica:
const existMovieInLikes= localStorage.liked_movies.includes(movie.id); console.log(existMovieInLikes) if (existMovieInLikes){ movieBtn.classList.add("movie-btn","movie-btn--liked"); }else{ movieBtn.classList.add("movie-btn") } movieBtn.addEventListener("click", ()=>{ movieBtn.classList.toggle("movie-btn--liked") likeMovie(movie); insertFavoritedMovies(); /* Y aca hice que se ejecute la accion cada vez que se haga click en el boton para actualizar la seccion de likes*/ })
`que se ejecute la funcion*
Mi solucion fue crear una funcion que verifica si movie-id esta en la lista de localStorage, y si ese es el caso, entonces agregar la clase movie-btn--liked
aqui dejo mi solucion
function isLiked(id) { const movieList = likedMovieList(); return movieList[id] ? true : false } if(isLiked(movie.id)){ movieBtn.classList.add('movie-btn--liked'); }
Solo hay ejecutar getLikedMovies() en el evento click de del movie btn
$movieBtn.addEventListener('click', () => { $movieBtn.classList.toggle('movie-btn--liked'); likeMovie(movie); //esta es la línea agregada, sea actualizara cada vez que demos click al boton de like getLikedMovies(); })
Mi solucion
likeBtn.addEventListener("click", () => { likeBtn.classList.toggle("like-btn--liked"); likeMovie(movie); if(location.hash = "#home"){ getLikedMovies(); } });
Guardar favoritos en la API de TMDB
Les comparto la forma de agregar y eliminar las películas de favoritos usando la API de TMDB V3. Les dejo el código utilizando Axios como fetch. 😀
Recuerden leer siempre la documentación de la API atentamente, así no tienen dólares de cabeza como yo los tuve. 😅
fetch
Obtener request_token
const getRequestToken = async () => { const REQUEST_TOKEN_URL = 'authentication/token/new'; const init = { method : 'GET', headers : { 'Content-Type' : 'application/json;charset=utf-8' } }; const RESPONSE = await fetch(`${URL}/${REQUEST_TOKEN_URL}?api_key=${YOUR_API_KEY}`, init); const DATA = await RESPONSE.json(); const REQUEST_TOKEN = DATA.request_token; return REQUEST_TOKEN; };
Obtener session_id
Antes de obtener nuestro session_id tenemos que aceptar la autenticación de terceros desde nuestra cuenta de TMDB, lo realizamos desde la siguiente URL
www.themoviedb.org/authenticate/{your_request_token}.
Una vez aceptado ya podés seguir con el siguiente código.
const getSession = async () => { const SESSION_ID_URL = 'authentication/session/new'; const request_token = 'your_request_token'; const REQUEST_BODY = JSON.stringify({ request_token }); const init = { method : 'POST', headers : { 'Content-Type' : 'application/json;charset=utf-8' }, body : REQUEST_BODY }; // *Tenemos que aceptar, en nuestra cuenta de The Movie DB, la autenticación de terceros en https://www.themoviedb.org/authenticate/{request_token} const RESPONSE = await fetch(`${URL}/${SESSION_ID_URL}?api_key=${YOUR_API_KEY}`, init); const DATA = await RESPONSE.json(); const SESSION_ID = DATA.session_id; return SESSION_ID; };
Obtener account_id
const getAccountId = async () => { const SESSION_ID = 'your_session_id'; const ACCOUNT_URL = 'account'; const init = { method : 'GET', headers : { 'Content-Type' : 'application/json;charset=utf-8' }, }; const RESPONSE = await fetch(`${URL}/${ACCOUNT_URL}?api_key=${YOUR_API_KEY}&session_id=${SESSION_ID}`, init); const ACCOUNT = await RESPONSE.json(); const ID = ACCOUNT.id; return ID; };
Agregar o eliminar una película de favoritos
El parámetro favorite(boolean) es el que nos permite agregar o eliminar una película de favoritos.
favorite = true add movie.
favorite = false remove movie.
const addOrDeleteFavoriteMovie = async ({ media_id, remove = false }) => { // Si queremos eliminar la película de favoritos tenemos que pasar el parámetro favorite = false; const SESSION_ID = 'your_session_id'; const media_type = 'movie'; const favorite = !remove; const ACCOUNT_ID = await getAccountId(); const REQUEST_BODY = JSON.stringify({ media_type, media_id, favorite }); const init = { method : 'POST', headers : { 'Content-Type' : 'application/json;charset=utf-8' }, body : REQUEST_BODY }; const RESPONSE = await fetch(`${URL}/account/${ACCOUNT_ID}/favorite?api_key=${YOUR_API_KEY}&session_id=${SESSION_ID}`, init); const STATUS = await RESPONSE.json(); return STATUS; };
Ver las películas guardadas
const getFavoriteMovies = async () => { const SESSION_ID = 'your_session_id'; const ACCOUNT_ID = await getAccountId(); const init = { method : 'GET', headers : { 'Content-Type' : 'application/json;charset=utf-8' } }; const RESPONSE = await fetch(`${URL}/account/${ACCOUNT_ID}/favorite/movies?api_key=${YOUR_API_KEY}&session_id=${SESSION_ID}`); const DATA = await RESPONSE.json(); const MOVIES = DATA.results; return MOVIES; };
Axios
Una cosa para aclarar, el parámetro params son los query parameters y nuestro parámetro data es el body que utilizamos con fetch.
Creando instancia para usar la API
const config = { baseURL : 'https://api.themoviedb.org/3/', headers : { 'Content-Type' : 'application/json;charset=utf-8' }, params : { api_key : YOUR_API_KEY } }; const api = axios.create(config);
Obtener request_token
const getRequestToken = async () => { const RESPONSE = await api('authentication/token/new'); const DATA = RESPONSE.data; const REQUEST_TOKEN = DATA.request_token; return REQUEST_TOKEN; };
Obtener session_id
Antes de obtener nuestro session_id tenemos que aceptar la autenticación de terceros desde nuestra cuenta de TMDB, lo realizamos desde la siguiente URL
www.themoviedb.org/authenticate/{your_request_token}.
Una vez aceptado ya podés seguir con el siguiente código.
const getSession = async () => { const request_token = 'your_request_token'; const config = { params : { request_token } }; // *Tenemos que aceptar, en nuestra cuenta de The Movie DB, la autenticación de terceros en https://www.themoviedb.org/authenticate/{request_token} const RESPONSE = await api('authentication/session/new', config); const DATA = RESPONSE.data; const SESSION_ID = DATA.session_id; return SESSION_ID; };
Obtener account_id
const getAccountId = async () => { const session_id = 'your_session_id'; const config = { params : { session_id } }; const RESPONSE = await api('account', config); const ACCOUNT = RESPONSE.data; const ID = ACCOUNT.id; return ID; };
Agregar o eliminar una película de favoritos
El parámetro favorite(boolean) es el que nos permite agregar o eliminar una película de favoritos.
favorite = true add movie.
favorite = false remove movie.
const addOrDeleteFavoriteMovie = async ({ media_id, remove = false }) => { // Si queremos eliminar la película de favoritos tenemos que pasar el parámetro favorite = false; const session_id = 'your_request_token'; const media_type = 'movie'; const favorite = !remove; const ACCOUNT_ID = await getAccountId(); const config = { method : 'POST', params : { session_id }, data : { media_type, media_id, favorite } }; const RESPONSE = await api(`account/${ACCOUNT_ID}/favorite`, config); const STATUS = RESPONSE.data; return STATUS; };
Ver las películas guardadas
const getFavoriteMovies = async () => { const session_id = 'your_request_token'; const ACCOUNT_ID = await getAccountId(); const config = { params : { session_id } }; const RESPONSE = await api(`account/${ACCOUNT_ID}/favorite/movies`, config); const DATA = RESPONSE.data; const MOVIES = DATA.results; return MOVIES; };
PD: No puedo dejar los links directos a la explicación de cada sección de la página de TMDB, ya que el sistema de comentarios lo detecta como “enlace malicioso”. Si quieren mayor detalles, pueden ver directo en la página de la API.
Para actualizar la sección de favoritos siempre que se haga clic sobre el botón de corazón, modifiqué la función likeMovie(). Lo primero que creó el profesor en esa función fue una variable likedMovies que contiene a la ejecución de la función likedMoviesList(), entonces, justo después de que se reescribe la información en local storage, creé una nueva variable llamada NewLikedMovies que contiene también a la ejecución de la función likedMoviesList() pero esta vez obviamente luego de la sobreescritura. Luego establezco un condicional para que si hay diferencia entre la primera variable y la segunda, ejecute la función getLikedMovies();
Así queda la función:
function likeMovie(movie) { const likedMovies = likedMoviesList(); console.log(likedMovies); if(likedMovies[movie.id]) { likedMovies[movie.id] = undefined; console.log('La pelicula ya esta en storage'); } else { likedMovies[movie.id] = movie; console.log('La pelicula no esta en storage'); } localStorage.setItem('liked_movies', JSON.stringify(likedMovies)); const NewlikedMovies = likedMoviesList(); if(likedMovies !== NewlikedMovies) { getLikedMovies(); } }