Yo lo que hice fue, agregarle a axios el parametro language
const api = axios.create({
baseURL: "https://api.themoviedb.org/3/",
params: {
"api_key": API_KEY,
"language": navigator.language || "es-ES"
}
})
Qué se debe optimizar en el frontend (y qué no)
Tu responsabilidad como frontend developer
Caché vs. memoria
Debuggeando caché y networking
Quiz: Qué se debe optimizar en el frontend (y qué no)
Optimización de imágenes
Loading spinners vs. loading skeletons
Reto: pantalla de carga
Intersection Observer
Lazy Loading
Imágenes por defecto
Quiz: Optimización de imágenes
Paginación
Scroll infinito vs. paginación
Botón de cargar más
Infinite Scrolling: evento de scroll
Infinite Scrolling: limitando la carga de datos
Infinite Scrolling: closures de navegación
Quiz: Paginación
Almacenamiento local
Local Storage vs. API real
Botón de like
Guardando películas en Local Storage
Lista de películas favoritas
Quiz: Almacenamiento local
Bonus
Reto: selección de idioma
Deploy
Próximos pasos
Más proyectos para tu portafolio
No tienes acceso a esta clase
¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera
Juan David Castro Gallego
Aportes 20
Preguntas 4
Yo lo que hice fue, agregarle a axios el parametro language
const api = axios.create({
baseURL: "https://api.themoviedb.org/3/",
params: {
"api_key": API_KEY,
"language": navigator.language || "es-ES"
}
})
Después de dos días buscando porqué diablos no podía acceder al valor de navigator.language, me di cuenta que la función que tengo para ver el cambio de hash en la URL se llama así “navigator” y sobre escribe el window.navigator de la API.
Si al poner el consola navigator.language te sale undefindes es por esto.
Saludos.
Cada vez me gusta más React, se vuelve mucho más sencillo todo, y puedes reutilizar código, y componentes.
En mi caso, para los lenguajes solamente agregué un select
para escoger Inglés, Español, oy Francés, también para el idioma predeterminado, estoy utilizando el Inglés, y si el usuario da permisos a nuestra app para acceder a sus datos, entonces utilizo el del usuario.
El error del final no sé muy bien por qué paso 😅
Idioma del navegador por defecto:
let lang = navigator.languages[1];
Array de idiomas:
const countries = [
{
name: "usa",
language: "en-US",
flag: '🇺🇸',
},
...
Crear opciones:
async function getLanguages() {
countries.forEach((country) => {
const languageOption = document.createElement('option');
languageOption.setAttribute('value', country.language );
languageOption.setAttribute('for', 'language');
const languageText = document.createTextNode(country.flag);
languageOption.appendChild(languageText);
languageOptions.appendChild(languageOption);
});
};
Seleccionar idioma:
languageOptions.addEventListener("change", (event) => {
lang = event.target.value;
homePage();
});
Agregar a cada llamado de la API:
params: {
language: lang,
},
cree un select con algunos idiomas
<select name="language" id="la">
<option value="en">English</option>
<option value="es">Spanish</option>
<option value="pt-BR">Portuguese Br</option>
<option value="fr">French</option>
</select>
una variable donde se cargara el idioma por defecto
let lang = 'en';
Y la funcion que realizara el cambio con un evento click
language.addEventListener('click', () => {
lang = language.value;
homePage();
})
La solución a esto sería primero comprobar si el navegador soporta el navigator.languages, si no, entonces debesmos prepararnos para asignar uno pordefecto, por ejemplo el español, y allí asignarlo a la api e ir implementándolo en todas las funciones!
Cree este objeto
const langs = [
{lang: 'es',
captions:
{
trends: 'Tendencias',
category: 'Categorias',
likedTitle: 'Peliculas Favoritas',
trendMore: 'Ver Más',
footerCaption: 'Hecho con amor en Platzi por @juandc',
selectLang : 'Seleccione Idioma',
search: 'Buscar',
}
},
{lang: 'en',
captions:
{ trends: 'Trends',
category: 'Categories',
likedTitle: 'Favorite Movies',
trendMore: 'More',
footerCaption: 'Made with love in Platzi by @juandc',
selectLang : 'Select a language',
search: 'Search',
}
},
{lang: 'pt',
captions:
{ trends: 'Tendências',
category: 'Categorias',
likedTitle: 'Filmes Favoritos',
trendMore: 'Ver mais',
footerCaption: 'Feito com amor em Platzi por @juandc',
selectLang : 'Selecione um idioma',
search: 'Procurar',
}
},
{lang: 'gr',
captions:
{ trends: 'Tendenzen',
category: 'Kategorien',
likedTitle: 'Lieblingsfilme',
trendMore: 'Mehr sehen',
footerCaption: 'Mit Liebe gemacht in Platzi von @juandc',
selectLang : 'Wähle eine Sprache',
search: 'Suche',
}
},
{lang: 'ar',
captions:
{ trends: 'اتجاهات',
category: 'فئات',
likedTitle: 'الأفلام المفضلة',
trendMore: 'المزيد',
footerCaption: 'صنع بكل حب في Platzi بواسطةjuandc',
selectLang : 'اختر لغة',
search: 'بحث',
}
},
{lang: 'fr',
captions:
{ trends: 'Les tendances',
category: 'Catégories',
likedTitle: 'voir plus',
trendMore: 'Mehr sehen',
footerCaption: 'Fait avec amour à Platzi par @juandc',
selectLang : 'Sélectionnez une langue',
search: 'Chercher',
}
},
]
Luego en main.js
const lang = document.getElementById('optionLanguages')
changeLanguage(navigator.language.substring(0,2))
window.addEventListener('languagechange', () => {
changeLanguage(lang.value = navigator.language.substring(0,2))
navigatorApp()
});
function changeLanguage(lang) {
//buscar lenguaje y asignarlo a un objeto
captions = langs.find(e => e.lang === lang)
if (captions == undefined) {
captions = langs.find(e => e.lang === 'es')
optionLanguages.value = 'es'
} else {
optionLanguages.value = lang
}
}
function optLang(lang) {
changeLanguage(lang)
navigatorApp()
}
En cada llamado al api se pasa la variable de Lang
Cree un select con los idiomas del primer objeto creado. Cuando el idioma se cambia por los settings del explorador, el evento se encarga de cambiar el idioma, buscar los titulos y refrescar la seccion que se esta mostrando.
En index .html
<label class="header-lang" for="lang">Choose a Language:</label>
<select id="optionLanguages" onchange="optLang(this.value)">
<option value="gr">Alemán</option>
<option value="ar">Arabe</option>
<option value="es" selected='selected'>Español</option>
<option value="fr">Francés</option>
<option value="en">Inglés</option>
<option value="pt">Portugues</option>
</select>
Cree esta constante y la pase como un parámetro junto a la api_key así: ‘language’: leng
const leng = window.navigator.language.split('-')[0]
window.navigator.language da una respuesta algo así como ‘es-419’. El .split es para obtener lo que esta antes del guion. Mi pregunta es, ¿para que es el otro numero???
Al inicio del main.js agregue una constante language y esa constante la paso en el axios por parametros.
const language = window.navigator.language;
const api = axios.create({
baseURL: 'https://api.themoviedb.org/3/',
headers: {
'Content-Type': 'application/json;charset=utf-8',
},
params: {
'api_key': API_KEY,
'language': language
},
});```
Bueno basicamente englobe el titulo de la pagina con el selector de idioma donde inserte 4 lenguajes populares como prueba:
<div class="header-title-lang">
<h1 class="header-title">PlatziMovies</h1>
<article class="header-language">
<img
src="img/icons8-argentina-48.png"
class="flag-img"
alt="Español - Argentina"
data-lang="es-AR"
/>
<img
src="img/icons8-france-48.png"
class="flag-img"
alt="Francois - France"
data-lang="fr-FR"
/>
<img
src="img/icons8-brazil-48.png"
class="flag-img"
alt="pt-BR"
data-lang="pt-BR"
/>
<img
src="img/icons8-great-britain-48.png"
class="flag-img"
alt="en-EN"
data-lang="en-EN"
/>
</article>
</div>
Diseñe dos nuevas funciones donde en la primera alojo el valor del idioma en un dataset de las imagenes para que al ser clickeadas guarden ese valor en localStorage recordando asi las preferencias del usuario en futuras visitas. Mientras que en la segunda modifico los titulos y demas contenido de texto que hemos hardcodeado en la pagina para que se adepten al idioma seleccionado
function assignLang(container) {
const lenguajes = Array.from(container.querySelectorAll('img'));
lenguajes.forEach((lenguaje) => {
lenguaje.addEventListener('click', () => {
localStorage.setItem('language', lenguaje.getAttribute('data-lang'))
translator(localStorage.getItem('language'));
location.reload();
});
});
}
function translator(langParam) {
if (langParam == "es-AR") {
movieDetailDescription.textContent ="No hay descripción disponible para la película actual. Echa un vistazo y puede que encuentres otra película que te guste.";
}
if (langParam == "fr-FR") {
searchFormInput.setAttribute("placeholder", "Recherche d'un film");
trendingPreviewTitle.innerText = "Tendances";
trendingBtn.innerText = "Voir plus";
categoriesPreviewTitle.innerText = "Catégories";
relatedMoviesTitle.innerText = "Films similaires";
likedTitle.innerText = "Films préférés";
footerTitle.innerHTML = "Réalisé par @Dmaledicte";
movieDetailDescription.textContent = "Aucune description n'est disponible pour le film actuel. Jetez un coup d'œil et vous trouverez peut-être un autre film qui pourrait vous plaire";
}
if (langParam == 'pt-BR') {
searchFormInput.setAttribute("placeholder", "Pesquisar um filme");
trendingPreviewTitle.innerText = "Tendências";
trendingBtn.innerText = "Ver mais";
categoriesPreviewTitle.innerText = "Categorias";
relatedMoviesTitle.innerText = "Filmes semelhantes";
likedTitle.innerText = "Filmes favoritos";
footerTitle.innerHTML = "Direção de @Dmaledicte";
movieDetailDescription.textContent = "Nenhuma descrição está disponível para o filme atual. Dê uma olhada e você pode encontrar outro filme que você pode gostar";
}
if (langParam == 'en-EN') {
searchFormInput.setAttribute("placeholder", "Look for a movie");
trendingPreviewTitle.innerText = "Trends";
trendingBtn.innerText = "See more";
categoriesPreviewTitle.innerText = "Categories";
relatedMoviesTitle.innerText = "Similar movies";
likedTitle.innerText = "Favourite movies";
footerTitle.innerHTML = "Made by @Dmaledicte";
movieDetailDescription.textContent = "There are no available descriptions for the current. Take a look around and you might find something you would like";
}
}
Luego en Axios inserto un nuevo Param que en caso de que no exista ninguna preferencia almacenada en localStorage utilice el lenguaje del navegador del usuario:
"language": localStorage.getItem('language')? localStorage.getItem('language') : navigator.language,
Detalles a tener en cuenta
-Es necesario establecer un refresh de pagina al seleccionar un nuevo idioma para que Axios tome correctamente el nuevo valor de language.
-Setear una ejecucion de translator en nuestro navigator para que se traduzca correctamente el contenido.
Viendo si ver o no la siguiente clase por lo que dijo el prof de LLORAR SANGRE…
Hola, todo bien solucionado, no sé si de la mejor forma pero funcionó, solo me quedó un bug, al añadir una peli a favoritos se me queda agregada con el idioma que tenía en el momento de agregarla, ya luego no se actualiza, lo seguiré viendo a ver si se soluciona.
De lo demás creé un array con los principales idiomas, e incluí el selector en el html y de forma dinámica con JS, fuí agregando cada idioma.
Luego creé una variable lang, con valor del navigator.language y creé un evento para observar cuándo se cambiaba una option del selector y se va cambiando el valor de lang, y llamo ahí dentro getTrendingMoviesPreview (), getCategoriesMoviesPreview (), getLikedMovies(), para que se actualicen.
El parámetro ‘language’, se lo tuve que pasar a cada función, porque no me funcionaba pasándola directamente al llamado de la api:
// variable lang
let lang = navigator.language;
// array de lenguajes
const languages = [
{
"iso_639_1": "en",
"english_name": "English",
"name": "English"
},
{
"iso_639_1": "fr",
"english_name": "French",
"name": "français"
},
{
"iso_639_1": "de",
"english_name": "German",
"name": "Deutsche"
},
{
"iso_639_1": "it",
"english_name": "Italian",
"name": "Italiano"
},
{
"iso_639_1": "zh",
"english_name": "Chinese",
"name": "漢語"
},
{
"iso_639_1": "es",
"english_name": "Spanish",
"name": "Español"
},
]
// función para crear el selector, y crear el evento de cambio de lenguaje:
function createLanguages(){
selectContainLanguaje.innerText = ''
languages.forEach(language=>{
let optionLanguage = document.createElement('option');
optionLanguage.name = language.english_name;
optionLanguage.innerText = language.name;
optionLanguage.value = language.iso_639_1;
selectContainLanguaje.appendChild(optionLanguage)
})
selectContainLanguaje.addEventListener('change', (e)=>{
console.log(e.target)
lang = e.target.value
console.log(lang)
getTrendingMoviesPreview ()
getCategoriesMoviesPreview ()
getLikedMovies()
})
}
// a cada función le pasé el parámetro de lenguaje
async function getTrendingMoviesPreview (){
const {data} = await api('trending/movie/day', {
params: {
'language': lang,
}
})
const movies = data.results;
createMovies(movies, trendingMoviesPreviewList, {lazyLoad:true, cleanPage:true});
}
Al inicio del archivo main.js, creé una variable language cuyo valor es navigator.language
let language = navigator.language;
Luego, dentro de la constante api donde llamamos a axios, agrego dentro de params un nuevo parámetro que tenga el valor de la variable creada antes.
const api = axios.create({
baseURL: 'https://api.themoviedb.org/3/',
headers: {
'Content-Type': 'application/json;charset=utf-8',
},
params: {
'api_key': API_KEY,
'language': language,
},
});
Cambio el idioma del navegador y efectiamente muestra la información de las películas en el idioma correspondiente.
Al agregar idiomas como el español, hay que tener en cuenta que debemos usar **decodeURI **en varios textos, que por tener por ejemplo acentos, están codificados.
Yo resolví lo del idioma de este modo:
//Data
const lang= localStorage.language;
lan.value = lang !== '' ? lang : 'en';
if(lan.value == "en"){
trendingPreviewTitle.innerHTML = 'Trends'
}
lan.addEventListener('change', () => {
localStorage.setItem('language', lan.value);
location.reload();
})
const api = axios.create({
baseURL: 'https://api.themoviedb.org/3',
headers: {
'Content-Type': 'application/json; charset=utf-8',
},
params: {
'api_key': API_KEY,
'language': lan.value,
},
});
En el archivo navigation.js , agregue un switch para traducir los titulos y botones al ejecutarse la funcion homePage() :
switch(lan.value){
case 'en':
trendingPreviewTitle.innerHTML = 'Trends';
trendingBtn.innerHTML = 'See more';
categoriesPreviewTitle.innerHTML = 'Categories';
likedTitle.innerHTML = 'Favorite movies';
break;
case 'fr':
trendingPreviewTitle.innerHTML = 'Les tendances';
trendingBtn.innerHTML = 'Voir plus';
categoriesPreviewTitle.innerHTML = 'Catégories';
likedTitle.innerHTML = 'Films préférés';
break;
case 'pt-BR':
trendingPreviewTitle.innerHTML = 'Tendências';
trendingBtn.innerHTML = 'Ver mais'
categoriesPreviewTitle.innerHTML = 'Categorias';
likedTitle.innerHTML = 'Filmes favoritos';
break;
default:
trendingPreviewTitle.innerHTML = 'Tendencias';
break;
}
En el Html agregue un select para elegir entre varios idiomas:
<select name="languaje" id="lang">
<option class="optLang" value="fr">🇫🇷</option>
<option class="optLang" value="es-ES">🇪🇸</option>
<option class="optLang" value="en">🇺🇸</option>
<option class="optLang" value="pt-BR">🇧🇷</option>
<option class="optLang" value="es-VE">🇻🇪</option>
</select>
nada no pude completar el reto por más que lo intente lo logre hacer despues de un tiempo pero no me cargaban los nombre de html de los idiomas y abandone el reto 😦
“Ayudar con la trava” 🤣🤣
¿Quieres ver más aportes, preguntas y respuestas de la comunidad?