<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/"
    xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
    <channel>
        
        <title>
            <![CDATA[ Mauricio Ignacio Fuentes Bravo - freeCodeCamp.org ]]>
        </title>
        <description>
            <![CDATA[ Descubre miles de cursos de programación escritos por expertos. Aprende Desarrollo Web, Ciencia de Datos, DevOps, Seguridad y obtén asesoramiento profesional para desarrolladores. ]]>
        </description>
        <link>https://www.freecodecamp.org/espanol/news/</link>
        <image>
            <url>https://cdn.freecodecamp.org/universal/favicons/favicon.png</url>
            <title>
                <![CDATA[ Mauricio Ignacio Fuentes Bravo - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/espanol/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Fri, 08 May 2026 14:10:43 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/espanol/news/author/mauricio-fuentes-b/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ Tutorial React: Construir un generador de lista de películas con React y HarperDB ]]>
                </title>
                <description>
                    <![CDATA[ En este tutorial construiremos un generador de películas simple que genera automáticamente una nueva película cada 40 segundos. También tiene un botón llamado "Generar nueva película" para mostrar otra película bajo demanda. Esta aplicación mostrará una película junto con su título, fecha de lanzamiento, calificación de fans, duración, una descripción ]]>
                </description>
                <link>https://www.freecodecamp.org/espanol/news/tutorial-react-construir-un-generador-de-lista-de-peliculas-con-react-y-harperdb/</link>
                <guid isPermaLink="false">62d33864b4def5085197306e</guid>
                
                    <category>
                        <![CDATA[ React ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Mauricio Ignacio Fuentes Bravo ]]>
                </dc:creator>
                <pubDate>Wed, 27 Jul 2022 19:07:18 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/espanol/news/content/images/2022/07/HarperDBMovieCover.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artículo original:</strong> <a href="https://www.freecodecamp.org/news/react-tutorial-build-a-movie-list-generator-with-react-and-harperdb/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">React Tutorial – Build a Movie List Generator with React and HarperDB</a>
      </p><p><em>En este tutorial construiremos un generador de películas simple que genera automáticamente una nueva película cada 40 segundos. También tiene un botón llamado "Generar nueva película" para mostrar otra película bajo demanda.</em></p><p>Esta aplicación mostrará una película junto con su título, fecha de lanzamiento, calificación de fans, duración, una descripción corta, estrellas, nombre de los directores y finalmente un botón que enlaza con la página de películas IMDb.</p><p>Puedes acceder al código completo de este proyecto (autor original) en el repositorio <a href="https://github.com/KingsleyUbah/harperdb-movie-generator">Github</a>.</p><h2 id="-c-mo-vamos-a-construir-esto">¿Cómo vamos a construir esto?</h2><p>Como con la mayoría de otras aplicaciones web, esta app consiste en un frontend y un backend.</p><p>El frontend es la parte que el usuario usa para interactuar. En nuestra app, el front end estará hecho de imágenes de carátulas de películas, su información, y un botón que linkea a la página de películas IMDb.</p><p>El backend es donde la data de las películas - tal como el título, descripción, actores, fotografía, etc.</p><p>La aplicación generará automáticamente una nueva película aleatoria cada 40 segundos.</p><p>Construiremos el frontend de nuestra aplicación usando React. React es una librería frontend de JavaScript usada para construir componentes de la interfaz de usuario (UI) reusables, tales como botones, menús de navegación, cartas y más.</p><p>También daremos el estilo a nuestros componentes usando CSS puro.</p><h2 id="como-construiremos-el-back-end">Como construiremos el Back End</h2><p>El backend de un sitio web contiene típicamente una base de datos, que es un programa que usa para almacenar y manipular data. La base de datos también tiene que ser accesible vía una API de modo que nuestro frontend pueda acceder a la data y disponerla a los usuarios.</p><p>Para lograr esto usaremos una herramienta interesante y entretenida llamada <strong>HarperDB</strong>.</p><h2 id="-qu-es-harperdb">¿Qué es HarperDB?</h2><p>HarperDB es un software de base de datos y gestor de base de datos que es increíblemente rápido - se ha probado que puede ser 37 veces más rápido que MongoDB.</p><p>La velocidad de una base de datos se refiere tanto a cuan rápido puede leer y escribir data a sus registros, como al computo sobre esa data.</p><p>HarperDB también es increíblemente flexible. Te permite hacer lo siguiente:</p><!--kg-card-begin: markdown--><ul>
<li>Te permire hacer consultas a un único endpoint.</li>
<li>Usar tanto SQL como NoSQL para consultar tu base de datos.</li>
<li>Subir data en Json y con consultas SQL.</li>
</ul>
<!--kg-card-end: markdown--><p>Si estás trabajando con mucha data, puedes importar toda ella en un solo paso en un archivo CSV. ¡Está buena la cosa!</p><p>No tienes que definir los tipos de datos para tu data, ya que HarperDB lo hace dinámicamente por ti. Sin mencionar su simple interfaz para administrar tus instancias en la nube sin problemas.</p><p>Como dije, es muy flexible.</p><h2 id="prerrequisitos-para-este-tutorial">Prerrequisitos para este tutorial</h2><p>Para construir esta app asumiré que tienes conocimientos básicos de los siguientes lenguajes y herramientas:</p><p><strong>Npm u otro gestor de paquetes</strong>: Necesitaremos esto para instalar React y un hook de HarperDB para React llamado <a href="https://www.npmjs.com/package/use-harperdb">use-harperdb</a> en tu proyecto.</p><!--kg-card-begin: markdown--><p>NPM es un acronimo de Node Package Manager (Gestor de paquetes Node). Es una herramienta que conecta tu proyecto local al registro npm, donde hay millones de paquetes de código público, tales como React y <code>useharperdb</code>. También te ayudará a gestionar su código una vez instalado.</p>
<!--kg-card-end: markdown--><!--kg-card-begin: markdown--><p>Debes asegurarte de tener una versión de Node 12.xx o superior instalada en tu equipo. Puedes chequear tu versión de node con el comando: <code>node-v</code></p>
<!--kg-card-end: markdown--><p><strong>SQL</strong>: En este proyecto usaremos una o dos consultas básicas, así que no te preocupes si no sabes mucho sobre SQL.</p><p>SQL es un acrónimo de Structured Query Language (Lenguaje Estructurado de Consultas). Es un lenguaje popular usado en la consulta de bases de datos relacionales. Lo usaremos en nuestro Hook para consultar nuestra instancia cloud de HarperDB para la data.</p><p><strong>React</strong>: Nuestra interfaz de usuario se construirá con React. Si sabes JavaScript, entonces aprender React es relativamente sencillo.</p><p><strong>Una cuenta de HarperDB</strong>: Si no tienes una cuenta de HarperDB, necesitarás <a href="https://studio.harperdb.io/sign-up">crear una</a>. No te preocupes, es completamente gratuita. Te mostraré como crear una cuenta más abajo.</p><p><strong>Y finalmente, CSS</strong>: Usaremos un poco de CSS para agregar estilo a nuestros elementos.</p><h2 id="-qu-son-los-hooks-de-react">¿Qué son los Hooks de React?</h2><p>En el pasado, para trabajar con un componente de React, tenías que definir el componente como un componente de clase. Esto cambió cuando React introdujo los Hooks.</p><p>Dicho de forma simple, los Hooks son funciones que te permiten trabajar con la data en un componente sin clase de React (que sea funcional).</p><p>Gracias a esto, no tienes que definir un componente de clase React sólo para manejar data dentro de él.</p><!--kg-card-begin: markdown--><p>El Hook <code>use-harperdb</code> te permite "enganchar" (hook) tu aplicación a tu instancia cloud de la base de datos para obtener data. Piensa en esto como un puente entre tu app React (Front End) y la base de datos HarperDB (Back End).</p>
<!--kg-card-end: markdown--><h2 id="c-mo-configurar-la-base-de-datos">Cómo configurar la base de datos</h2><p>HarperDB es una base de datos flexible, como mencioné antes. Esto te permite usar sus servicios ya sea, configurando tu propio servidor local HarperDB o usando la arquitectura serverless (sin servidor).</p><p>En este proyecto usaremos la arquitectura serverless. Esto significa que no implementaremos un servidor (este es el backend) en tu máquina local. En su lugar, aprovecharemos la infraestructura en la nube de HarperDB para administrar nuestra data de películas y hacerla accesible para nuestra app.</p><h2 id="configurando-la-instancia-cloud-de-harperdb">Configurando la instancia Cloud de HarperDB</h2><p>Primero, asumiré que creaste una cuenta gratis como solicité antes. Si no lo has hecho, anda y <a href="https://studio.harperdb.io/sign-up">crea una</a></p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/espanol/news/content/images/2022/07/image-13.png" class="kg-image" alt="image-13" srcset="https://www.freecodecamp.org/espanol/news/content/images/size/w600/2022/07/image-13.png 600w, https://www.freecodecamp.org/espanol/news/content/images/size/w1000/2022/07/image-13.png 1000w, https://www.freecodecamp.org/espanol/news/content/images/size/w1600/2022/07/image-13.png 1600w, https://www.freecodecamp.org/espanol/news/content/images/2022/07/image-13.png 1919w" sizes="(min-width: 720px) 720px" width="1919" height="895" loading="lazy"></figure><p>Te pedirá el nombre, una dirección e-mail válida y un nombre de subdominio para tu instancia cloud. Con esto HarperDB creará un nombre de sub-dominio para ti.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/espanol/news/content/images/2022/07/image-14.png" class="kg-image" alt="image-14" srcset="https://www.freecodecamp.org/espanol/news/content/images/size/w600/2022/07/image-14.png 600w, https://www.freecodecamp.org/espanol/news/content/images/2022/07/image-14.png 1000w" sizes="(min-width: 720px) 720px" width="1000" height="458" loading="lazy"><figcaption>Asegúrate de elegir un password seguro</figcaption></figure><p>Luego, crearemos una instancia cloud:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/espanol/news/content/images/2022/07/image-16.png" class="kg-image" alt="image-16" srcset="https://www.freecodecamp.org/espanol/news/content/images/size/w600/2022/07/image-16.png 600w, https://www.freecodecamp.org/espanol/news/content/images/2022/07/image-16.png 928w" sizes="(min-width: 720px) 720px" width="928" height="460" loading="lazy"></figure><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/espanol/news/content/images/2022/07/image-17.png" class="kg-image" alt="image-17" srcset="https://www.freecodecamp.org/espanol/news/content/images/size/w600/2022/07/image-17.png 600w, https://www.freecodecamp.org/espanol/news/content/images/2022/07/image-17.png 630w" width="630" height="538" loading="lazy"></figure><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/espanol/news/content/images/2022/07/image-18.png" class="kg-image" alt="image-18" srcset="https://www.freecodecamp.org/espanol/news/content/images/size/w600/2022/07/image-18.png 600w, https://www.freecodecamp.org/espanol/news/content/images/2022/07/image-18.png 633w" width="633" height="586" loading="lazy"><figcaption>Llena con tus datos</figcaption></figure><p>Aquí te pedirá que agregues el nombre de la instancia. No te preocupes, puedes colocar cualquier nombre fácilmente recortable, pero es mejor hacerlo descriptivo.</p><p>Para crear la URL de tu instancia, la que necesitarás en tu app cuando consultes data, HarperDB combinara el nombre de tu instancia con el nombre de tu subdominio. También se te pedirá configurar las credenciales de tu instancia (nombre de usuario y password).</p><p>Luego, seleccionamos las especificaciones de las instancias. Por el bien de este tutorial usaremos el plan gratuito. También necesitas elegir una región para tu instancia.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/espanol/news/content/images/2022/07/image-19.png" class="kg-image" alt="image-19" srcset="https://www.freecodecamp.org/espanol/news/content/images/size/w600/2022/07/image-19.png 600w, https://www.freecodecamp.org/espanol/news/content/images/2022/07/image-19.png 637w" width="637" height="857" loading="lazy"></figure><p>Haz click en "Confirm Instance Details" y te enviará a una página que contiene toda la información de tu instancia. Ahora copia el URL, tu nombre de usuario y tu password y guardalos. Los necesitarás más tarde.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/espanol/news/content/images/2022/07/image-20.png" class="kg-image" alt="image-20" srcset="https://www.freecodecamp.org/espanol/news/content/images/size/w600/2022/07/image-20.png 600w, https://www.freecodecamp.org/espanol/news/content/images/2022/07/image-20.png 1000w" sizes="(min-width: 720px) 720px" width="1000" height="458" loading="lazy"><figcaption>Guarda tu URL, username y password</figcaption></figure><p>Cuando estés preparado haz clic en "Add Instance". Te llevará a una página que mostrará una carta de tu instancia. Tu instancia necesitará un poco de tiempo inicialmente antes de que puedas usarla, pero podemos hacer algunas cosas mientras esperamos</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/espanol/news/content/images/2022/07/image-21.png" class="kg-image" alt="image-21" srcset="https://www.freecodecamp.org/espanol/news/content/images/size/w600/2022/07/image-21.png 600w, https://www.freecodecamp.org/espanol/news/content/images/size/w1000/2022/07/image-21.png 1000w, https://www.freecodecamp.org/espanol/news/content/images/size/w1600/2022/07/image-21.png 1600w, https://www.freecodecamp.org/espanol/news/content/images/2022/07/image-21.png 1905w" sizes="(min-width: 720px) 720px" width="1905" height="888" loading="lazy"></figure><h2 id="como-configurar-la-aplicaci-n-react">Como configurar la aplicación React</h2><p>Mientras nuestra instancia cloud está siendo configurada, podemos tomar la oportunidad de configurar el directorio para nuestra app.</p><p>Primero inicializamos nuestro proyecto ejecutando el siguiente comando en cualquier terminal:</p><!--kg-card-begin: markdown--><pre><code>npx create-react-app harperdb-movies-generator</code></pre>
<!--kg-card-end: markdown--><p>Este comando creará una carpeta llamada harperdb-movies-app e instalará todas las dependencias que necesitaremos para nuestro proyecto. Esto incluye React y ReactDOM, de modo que no tendremos que hacerlo manualmente.</p><p>Ahora vamos a ejecutar el comando que traerá el Hook use-harperdb a nuestro proyecto. Este Hook nos ayudará a conectar nuestra instancia cloud. Para instalarlo, ejecutaremos el siguiente comando en nuestra terminal:</p><!--kg-card-begin: markdown--><p><code>cd harperdb-movies-app</code></p>
<!--kg-card-end: markdown--><p>Para cambiar a la raíz de nuestro proyecto</p><!--kg-card-begin: markdown--><p>(A la fecha de traducción del tutorial <code>use-harperdb</code> era compatible con <code>React 17.0.2</code>, mientras que la versión actual era la 18.x.x, es por esto que usaremos los flags <code>--legacy-peer-deps</code> y <code>--force</code> para que se ajusten las dependencias de la aplicación</p>
<!--kg-card-end: markdown--><!--kg-card-begin: markdown--><pre><code>npm install use-harperdb --legacy-peer-deps --force</code></pre>
<!--kg-card-end: markdown--><p>Y eso fue todo con la configuración!</p><h2 id="como-integrar-harperdb-a-nuestra-app-react">Como integrar HarperDB a nuestra App React</h2><p>Ahora que el hook use-harperdb se ha instalado, tenemos que hacer una cosa más para poder acceder a la base de datos y hacer operaciones CRUD en ella: tenemos que conectar nuestra app a la instancia cloud. Esto lo haremos con el HarperDBProvider.</p><p>Antes de entrar a esta tarea, necesitamos hacer algo primero. Cuando construimos una aplicación CRUD, no es una buena práctica exponer credenciales tales como llaves de API a otras personas, especialmente si tenemos la intención de llevar código a un repositorio público como GitHub.</p><p>Para proteger cualquier credencial sensible, necesitamos almacenarlas como variables de entorno. Este es un archivo que almacenará todas las credenciales sensibles, tales como passwords, llaves de API, y en nuestro caso particular, las credenciales de nuestra instancia cloud (URL, nombre de usuario y password).</p><!--kg-card-begin: markdown--><p>Crea un <code>.env</code> en la raíz del directorio del proyecto. Puedes hacerlo en tu editor de código, click derecho en la raíz del directorio (harperdb-movie-generator) y seleccionar la opción "crear nuevo archivo".</p>
<p>Llama a este archivo <code>.env</code> y presiona enter. este creará un <code>.env</code> dentro de harperdb-movie-generator. Después de esto, define las siguientes variables:</p>
<pre><code>REACT_APP_DB_URL=**
REACT_APP_USER=**
REACT_APP_PASSWORD=**</code></pre>
<!--kg-card-end: markdown--><p>Asegúrate de usar el mismo formato y pasar la información correcta de tu instancia cloud, en vez de los doble asterisco. Llena los datos con la URL, username y password que te dije que guardaras en algún lugar.</p><p>React leerá todas las variables de entorno que usen REACT_APP_ como prefijo, y luego dinámicamente pasará el valor cuando lo necesite.</p><p>Con el archivo .env creado, nuestra siguiente acción será envolver toda nuestra aplicación React dentro del HarperDBProvider que importamos.</p><p>HarperDBProvider se asegurará que nuestra app tenga el contexto de la base de datos HarperDB.</p><p>Para envolver nuestra aplicación React dentro del Provider, iremos al fichero index.js de nuestro proyecto e importaremos el Provider, y de forma segura pasaremos esas variables de entorno en al Provider. Esto deja saber cuales instancias conectar a nuestro front end</p><!--kg-card-begin: markdown--><pre><code>import React from 'react';
import ReactDOM from 'react-dom';  // Línea modificada
import './index.css';
import App from './App';
import { HarperDBProvider } from 'use-harperdb/useHarperDB';
import reportWebVitals from './reportWebVitals';


// Renderizado en DOM
ReactDOM.render(
  &lt;React.StrictMode&gt;
    // Hook de use-harperdb
    &lt;HarperDBProvider
    url={process.env.REACT_APP_DB_URL}
    user={process.env.REACT_APP_USER}
    password={process.env.REACT_APP_PASSWORD}
    &gt;
      &lt;App /&gt;
    &lt;/HarperDBProvider&gt;
  &lt;/React.StrictMode&gt;,
  document.getElementById("root")
);

// Si deseas comenzar a medir el rendimiento en su aplicación, pase una función
// para registrar los resultados (por ejemplo:reportWebVitals(console.log))
// o envia a un punto final de analytics. Más información: https://bit.ly/CRA-vitals
reportWebVitals();</code></pre>
<!--kg-card-end: markdown--><h2 id="como-poblar-nuestra-base-de-datos-con-data">Como poblar nuestra base de datos con data</h2><p>Si te acuerdas, dejamos nuestra instancia cloud mientras aún se estaba configurando. A estas alturas, deberíamos tener nuestra instancia configurada y lista para servir datos. En este caso deberíamos ver el estado OK en nuestra instancia</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/espanol/news/content/images/2022/07/image-22.png" class="kg-image" alt="image-22" srcset="https://www.freecodecamp.org/espanol/news/content/images/size/w600/2022/07/image-22.png 600w, https://www.freecodecamp.org/espanol/news/content/images/2022/07/image-22.png 1000w" sizes="(min-width: 720px) 720px" width="1000" height="462" loading="lazy"><figcaption>Instancia configurada</figcaption></figure><p>Tu instancia cloud debería estar lista para usar con tu front end conectado a la instancia también. Sin embargo, el Front End será inútil si no tiene datos (es decir, películas) para mostrar al usuario.</p><p>Es por esto que necesitamos poblar nuestra base de datos con películas. </p><p>Pero antes de eso, necesitamos crear un esquema para nuestra data de películas. Puedes pensar en un esquema como en una colección de tablas en nuestra base de datos. Yo simplemente llamaré a mi propio esquema "coleccion":</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/espanol/news/content/images/2022/07/image-23.png" class="kg-image" alt="image-23" width="467" height="349" loading="lazy"><figcaption>Creando el esquema y una tabla dentro de el</figcaption></figure><p>Luego crea una tabla. Llamaré a la mía "pelicula". Una tabla consistirá en registros de películas individuales</p><p>Cada película debe tener un hash attribute. Un hash_attribute es simplemente una columna con una única clave que identifica una fila de data en particular, y la distingue de la siguiente fila. Nosotros simplemente usaremos la columna "id" como nuestro hash_attribute.</p><p>Como estamos creando una app con más de una película, nuestra tabla consistirá en más de una fila con una película (es decir, registro de datos). También, como cada película tiene muchas propiedades tales como titulo, año, fecha de lanzamiento, etc, tendrá más de un campo de información.</p><p>Puedes subir las películas una por una con un único objeto JSON o puedes subir una colección entera de películas con un array de objetos JSON.</p><p>HarperDB te permite subir data principalmente de 3 formas:</p><!--kg-card-begin: markdown--><ol>
<li>Haciendo consultas SQL o NoSQL para crear data en nuestra base de datos.</li>
<li>Definiendo un único objeto JSON (para un registro) y un array de objetos JSON (para múltriples registros).</li>
<li>Importando y cargando data con un archivo CSV</li>
</ol>
<!--kg-card-end: markdown--><p>Para subir la información de una película, crearemos un objeto JSON el cual contendrá toda la información de una película. Aquí hay un ejemplo de la información en JSON:</p><!--kg-card-begin: markdown--><pre><code>{
  cover: 'https://res.cloudinary.com/ubahthebuilder/image/upload/v1627129180/avengers_endgame_ilqzqj.png',
  date: 2017,
  description: 'After the devastating events of Avengers: Infinity War (2018), the universe is in ruins. With the help of remaining allies, the Avengers assemble once more in order to reverse Thanos actions and restore balance to the universe.',
  directors: [
    'Anthony Russo',
    'Joe Russo'
  ],
  genres: [
    'Action',
    'Adventure',
    'Drama'
  ],
  hours: 3,
  id: 1,
  minutes: 1,
  rating: 8.4,
  stars: [
    'Robert Downey',
    'Chris Evans',
    'Mark Ruffalo'
  ],
  title: 'Avengers: End Game',
  website: 'https://www.imdb.com/title/tt4154796/',
  writers: [
    'Christopher Markus',
    'Stephen McFeely'
  ]
}
</code></pre>
<!--kg-card-end: markdown--><p>navega a la tabla <em>pelicula</em> dentro de la colección y haz clic en el botón + en la esquina superior derecha de la página, el cual está destacado en la siguiente imagen:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/espanol/news/content/images/2022/07/image-24.png" class="kg-image" alt="image-24" srcset="https://www.freecodecamp.org/espanol/news/content/images/size/w600/2022/07/image-24.png 600w, https://www.freecodecamp.org/espanol/news/content/images/size/w1000/2022/07/image-24.png 1000w, https://www.freecodecamp.org/espanol/news/content/images/2022/07/image-24.png 1258w" sizes="(min-width: 720px) 720px" width="1258" height="235" loading="lazy"><figcaption>Agregando una nueva película a nuestra tabla</figcaption></figure><p>Copia el JSON previamente definido y pégalo en el espacio provisto para ello, reemplazando todo lo que ahí por razones de formato. Haz clic en el botón verde para guardar la información en la tabla película.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/espanol/news/content/images/2022/07/image-26.png" class="kg-image" alt="image-26" srcset="https://www.freecodecamp.org/espanol/news/content/images/size/w600/2022/07/image-26.png 600w, https://www.freecodecamp.org/espanol/news/content/images/size/w1000/2022/07/image-26.png 1000w, https://www.freecodecamp.org/espanol/news/content/images/2022/07/image-26.png 1094w" sizes="(min-width: 720px) 720px" width="1094" height="590" loading="lazy"><figcaption>Pega el objeto JSON</figcaption></figure><p>Una vez que terminaste de subir la película, la tabla debería verse algo similar a esto.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/espanol/news/content/images/2022/07/image-25.png" class="kg-image" alt="image-25" srcset="https://www.freecodecamp.org/espanol/news/content/images/size/w600/2022/07/image-25.png 600w, https://www.freecodecamp.org/espanol/news/content/images/size/w1000/2022/07/image-25.png 1000w, https://www.freecodecamp.org/espanol/news/content/images/2022/07/image-25.png 1375w" sizes="(min-width: 720px) 720px" width="1375" height="178" loading="lazy"><figcaption>Una película dentro de nuestra tabla</figcaption></figure><p>Puedes usar la data del proyecto desde el <a href="https://github.com/MauricioTRP/harperdb-movies-generator">repositorio GitHub</a> para insertar múltiples películas de una vez.</p><h2 id="como-construir-nuestra-interfaz-de-usuario-y-consultar-la-base-de-datos">Como construir nuestra interfaz de usuario y consultar la base de datos</h2><p>Ahora que la data está lista, necesitamos mostrarla en nuestro front end para que el usuario pueda interactuar con ella.</p><p>Primero necesitamos modificar nuestro archivo app.js:</p><!--kg-card-begin: markdown--><pre><code>import React from 'react'
import './App.css';
import Pelicula from './components/Pelicula';

function App() {
  return (
    &lt;div className="App"&gt;
      &lt;div className="main-container"&gt;
        &lt;header&gt;
          &lt;h1 className="heading"&gt;Lista de películas&lt;/h1&gt;
          &lt;h3&gt;Un simple generador de películas hecho con React y HarperDB&lt;/h3&gt;
        &lt;/header&gt;
        &lt;div&gt;
          &lt;Pelicula/&gt;
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  );
}

export default App;</code></pre>
<!--kg-card-end: markdown--><p>Este será el componente de nivel superior en nuestro proyecto, donde importamos las librerías React, ReactDOM y la hoja de estilos App.css para nuestra aplicación.</p><p>Luego en el archivo App.css definiremos nuestros componentes de la app, los cuales retornarán el elemento header y el componente <em>Pelicula</em></p><p>Acá está el estilo para nuestra aplicación completa:</p><!--kg-card-begin: markdown--><pre><code>@import url('https://fonts.googleapis.com/css2?family=Lato:wght@300&amp;display=swap');
@import url('https://fonts.googleapis.com/css2?family=Roboto:wght@500&amp;display=swap');

/* Estilos base */

body{
  font-family:"lato", sans-serif;
  color: white;
  background-color: #082032;
}

a {
  color: black;
  font-family: "roboto", sans-serif;
  font-size: 3.1rem;
  text-decoration: none;
  display: inline-block;
}

h1 {
  text-align: center;
  font-family: "roboto", sans-serif;
  font-size: 3.5rem;
  font-weight:600;
}

h3 {
  text-align: center;
}

p {
  font-weight: 300;
}

span {
  color: #FFF338;
}

ul {
  list-style-type: none;
  display: flex;
  margin-left: 2rem;
}

li {
  outline-color: #2c394B;
  outline-style: inset;
  outline-width: 2px;
  outline-offset: 5px;
  margin: 11px;
  padding: 0px, 2px;
}

img {
  max-height: 500px;
  width: 70vw;
  margin: 0 auto;

}

/* Clases */

.carga{
  display: flex;
  justify-content: center;
  align-items: center;
  flex-direction: column;
}

.portada-pelicula{
  max-width: 800px;
  width: 90%;
  background-color: #2c394B;
  margin: 0 auto;
  border-radius: 10px;
}

.circulo {
  background-color: transparent;
  margin-right: 37px;
  text-align: center;
  margin-top: 50px;
  border: 3px solid #FFF338;
  height: 90px;
  border-radius: 50%;
  -moz-border-radius: 50%;
  -webkit-border-radius: 50%;
  width: 90px;
}

.ratings {
  font-size: 30px;
  margin-top: 12px;
}

.mitad-grande, .mitad-pequena {
  font-family: "roboto", sans-serif;
  font-style: oblique;
  color: white;
}

.mitad-pequena {
  color: #DAD0C2;
  font-size: 1.2rem;
}

.btn-visita-pelicula {
  margin: 1rem 2rem;
  padding: 1em 1em;
  top: 50px;
  left: 15px;
  font-size: 1.2rem;
  outline-style: solid;
  color: #FFF338;
  outline-color: #FFF338;
  outline-offset: 10px;
}

.btn-generar-pelicula {
  background-color: #FFF338;
  margin: 1rem 2rem;
  padding: 1em 1em;
  top: 50px;
  left: 15px;
  font-size: 1.2rem;
  text-decoration: none;
  text-transform: uppercase;
}

.btn-accion {
  width: inherit;
  display:flex;
  flex-direction: row;
  align-items: center;
  justify-content: center;
}

.titulo{
  font-size: 50px;
  padding-top: 40px;
  padding-left: 30px;
  margin-bottom: 0;
}

.info-arriba {
  display: flex;
  justify-content: space-between;
}

.info-soporte {
  padding-left: 30px;
  font-weight: bold;
  margin-bottom: 20px;
}

.info-abajo {
  font-family: "roboto", sans-serif;
  max-width: 70vw;
  margin: 1rem;
  text-align: center;

}

.autores {
  text-align: right;
  padding: 0;
}

.imagen {
  display: flex;
  align-items: center;
  padding-top: 2rem;
}

</code></pre>
<!--kg-card-end: markdown--><p>otra vez, puedes acceder al código completo para este proyecto desde el <a href="https://github.com/MauricioTRP/harperdb-movies-generator">repositorio Github.</a></p><h2 id="como-agregar-el-componente-pel-cula">Como agregar el componente Película</h2><p>Ahora necesitamos agregar nuestro componente película. Comenzaremos creando un nuevo directorio dentro del directorio "src" </p><!--kg-card-begin: markdown--><p>Ahora necesitamos agregar nuestro componente película. COmenzaremos creando un nuevo directorio <code>componentes</code> dentro del directorio <code>src</code>. Luego crearemos un archivo dentro de <code>componentes</code> llamado <code>Pelicula.js</code>. Aquí es donde viene lo bueno.</p>
<!--kg-card-end: markdown--><!--kg-card-begin: markdown--><p>Además de las librería <code>React</code>, importaremos también el hook <a href="https://www.npmjs.com/package/use-harperdb"><code>use-harperdb</code></a>.</p>
<!--kg-card-end: markdown--><!--kg-card-begin: markdown--><p>Vamos a ejecutar la función (Hook) <code>use-harperdb</code> pasandole un objeto como argumento. Dentro del objeto, necesitamos darle la propiedad "query". Esta propiedad determinará qué tipo de operaciones queremos hacer a nuestra base de datos.</p>
<!--kg-card-end: markdown--><!--kg-card-begin: markdown--><pre><code>import React from "react";
import { useHarperDB } from "use-harperdb"

function Pelicula(){
    // Llamada a hook use-harperdb

    const [data, loading, error, refresh] = useHarperDB(
        {
            query: {
                operation:'sql',
                sql: "select * from colecion.pelicula"
            },
            interval: 40000  // 40 segundos
        }
    );
    
// ... el código continúa más abajo</code></pre>
<!--kg-card-end: markdown--><!--kg-card-begin: markdown--><p>La primera propiedad dentro de la consulta <code>query</code>, es la propiedad <code>operation</code>, especifica de qué forma quieres consultar la data. En nuestro ejemplo lo haremos con comandos SQL.</p>
<!--kg-card-end: markdown--><!--kg-card-begin: markdown--><p>La segunda propiedad dentro de la consulta (<code>query</code>) es la propiedad SQL. Aquí es donde escribiremos nuestras consultas SQL para cualquier operación CRUD que queramos realizar. En nuestro caso, simplemente queremos traer las peliculas.</p>
<!--kg-card-end: markdown--><!--kg-card-begin: markdown--><pre><code>SELECT *FROM coleccion.pelicula</code></pre>
<!--kg-card-end: markdown--><p>(La forma en que se crean los identificadores cambió desde que se creó el artículo original, por lo que la consulta varía respecto a la consulta del autor original)</p><!--kg-card-begin: markdown--><p>Después de la consulta, podemos definir la propiedad opcional <code>interval</code>. Con esta propiedad puedes especificar cuanto tiempo tiene que esperar tu app antes que realice otra consulta de forma automática a la base de datos.</p>
<!--kg-card-end: markdown--><!--kg-card-begin: markdown--><p>Al ejecutar la función <code>useHarperDB</code> con estos parametros correctamente, nos devolverá un array conteniendo algunas cosas importantes. Abajo hay cuatro elementos importantes que obtendremos de <code>useHarperDB</code>:</p>
<ul>
<li><code>loading</code>: Este es un booleano que especifica si la base de datos sigue cargando la data o no. De esta forma, puedes colocar opcionalmente un "spinner" de carga.</li>
<li><code>error</code>: Esto indica si un error ha ocurrido mientras se consulta a la base de datos.</li>
<li><code>refresh</code>: Asumiento que no definiste un intervalo de forma adecuada, puedes llamar a esta función cuando quieras para obtener nueva data.</li>
<li><code>data</code>: El elemento principal. Si todas las cosas salen bien, HarperDB devolverá nuestra data a esta variable.</li>
</ul>
<!--kg-card-end: markdown--><h3 id="como-mostrar-la-data-en-nuestro-frontend">Como mostrar la data en nuestro frontend</h3><p>Con nuestra data retornada de forma exitosa de la base de datos, es tiempo de pasarla a nuestro template React:</p><!--kg-card-begin: markdown--><pre><code>    // renderizado cuando está cargando la data
    if(loading){
        return(&lt;div&gt;Cargando...&lt;/div&gt;)
    }

    // Renderizado en caso de obtener la data
    if(data){

        // Acá obtiene una película de forma aleatoria en báse al índice del array
        const aleatorio = Math.floor(Math.random()*6+1);

        return(&lt;div className="carga"&gt;
            {/* Portada */}
            &lt;div className="portada-pelicula"&gt;
                &lt;div className="info-arriba"&gt;
                    &lt;h2 className="titulo"&gt;{data[aleatorio].title}&lt;/h2&gt;
                    &lt;div className="circulo"&gt;
                        &lt;div className="ratings"&gt;
                            &lt;span className="mitad-grande"&gt;{data[aleatorio].rating}&lt;/span&gt;/&lt;span className="mitad-pequena"&gt;10&lt;/span&gt;
                        &lt;/div&gt;
                    &lt;/div&gt;
                &lt;/div&gt;
                &lt;div className="info-soporte"&gt;
                    &lt;span className="año"&gt;{data[aleatorio].date}&lt;/span&gt; -
                    &lt;span className="duracion"&gt; Duración {data[aleatorio].hours}h:{data[aleatorio].minutes}m&lt;/span&gt;
                &lt;/div&gt;
            &lt;/div&gt;

            &lt;div className="imagen"&gt;
                &lt;img alt="Portada Pelicula" src={data[aleatorio].cover} /&gt;
            &lt;/div&gt;

            &lt;div className="generos"&gt;
                &lt;ul className="generos-pelicula"&gt;
                    {data[aleatorio].genres.map((genero,index)=&gt;{
                        return(
                            &lt;li key={index}&gt;&lt;span className="generos-pelicula-item"&gt;{genero}&lt;/span&gt;&lt;/li&gt;
                        )
                    })}
                &lt;/ul&gt;
            &lt;/div&gt;

            &lt;div className="info-abajo"&gt;
                &lt;p&gt;{data[aleatorio].description}&lt;/p&gt;

                &lt;hr /&gt;
                &lt;p className="autores"&gt;Escritores:
                    {data[aleatorio].writers.map((escritores,index) =&gt;{
                        return(
                            &lt;span key={index} className="escritores"&gt;{escritores}&lt;/span&gt;
                            )
                        } )}
                &lt;/p&gt;
                &lt;p className="autores"&gt;Director/es:
                    {data[aleatorio].directors.map((directores,index)=&gt;{
                        return(
                            &lt;span key={index} className="directores"&gt;{directores}&lt;/span&gt;
                        )
                    })}
                &lt;/p&gt;
                &lt;hr /&gt;
                &lt;div className="btn-accion"&gt;
                    &lt;a className="btn-visita-pelicula" href={data[aleatorio].website}&gt;Mira en IDBM&lt;/a&gt;
                    &lt;a className="btn-generar-pelicula" href="" onClick={refresh}&gt;Otra Pelicula&lt;/a&gt;
                &lt;/div&gt;
            &lt;/div&gt;
        &lt;/div&gt;)
    }

    // Renderizado en caso de error de conexión
    if(error){
        return(&lt;div className=""&gt;Lo sentimos, no encontramos la información {error}&lt;/div&gt;)
    }</code></pre>
<!--kg-card-end: markdown--><p>No olvides exportar el componente para usarlo en App.js</p><p>Si estás familiarizado con React, esto no debería ser extraño para ti. Pero de todas formas explicaré lo que hice acá:</p><!--kg-card-begin: markdown--><ul>
<li>Como dije, la función <code>useHarperDB</code> retornará nuestra data. En nuestro caso hicimos una consulta <code>query</code> para obtener todas las películas, lo que retornó un array con películas. Como requeríamos una sóla película, creamos un número aleatorio cada vez que carga, para acceder a una pelicula de forma aleatoria en base a su índice <code>data[aleatorio].llave</code></li>
<li>Luego tenemos que revisar si la data fue devuelta. Si no hay data simplemente renderizamos un div que muestra el mensaje "Lo sentimos, no encontramos la información".</li>
<li>Si recibimos la data, pasaremos esta data a nuestro template. Extraemos data campo de nuestro objeto y lo pasamos en el lugar correcto de nuestro template.</li>
</ul>
<!--kg-card-end: markdown--><p>Cuando terminamos, finalmente ejecutamos el siguiente comando en la consola:</p><!--kg-card-begin: markdown--><pre><code>npm start .env</code></pre>
<!--kg-card-end: markdown--><!--kg-card-begin: markdown--><p>con el <code>.env</code> te aseguras que pueda leer las variables de entorno que creamos</p>
<!--kg-card-end: markdown--><p>Esto debería ejecutar nuestro servidor de desarrollo en https://localhost:3000. si toda va bien, deberías ver la aplicación en nuestro navegador.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/espanol/news/content/images/2022/07/image-27.png" class="kg-image" alt="image-27" srcset="https://www.freecodecamp.org/espanol/news/content/images/size/w600/2022/07/image-27.png 600w, https://www.freecodecamp.org/espanol/news/content/images/size/w1000/2022/07/image-27.png 1000w, https://www.freecodecamp.org/espanol/news/content/images/2022/07/image-27.png 1320w" sizes="(min-width: 720px) 720px" width="1320" height="853" loading="lazy"><figcaption>Así debería verse nuestra app</figcaption></figure><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/espanol/news/content/images/2022/07/image-28.png" class="kg-image" alt="image-28" srcset="https://www.freecodecamp.org/espanol/news/content/images/size/w600/2022/07/image-28.png 600w, https://www.freecodecamp.org/espanol/news/content/images/size/w1000/2022/07/image-28.png 1000w, https://www.freecodecamp.org/espanol/news/content/images/2022/07/image-28.png 1025w" sizes="(min-width: 720px) 720px" width="1025" height="540" loading="lazy"></figure><p>Con esto tendríamos nuestra app! :) </p><h3 id="como-implementar-la-aplicaci-n-en-las-p-ginas-github">Como implementar la aplicación en las páginas GitHub</h3><p>Bienvenido a la última sección del tutorial. Implementaremos nuestra nueva aplicación en las páginas de GitHub para que el mundo la vea.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/espanol/news/content/images/2022/07/image-29.png" class="kg-image" alt="image-29" srcset="https://www.freecodecamp.org/espanol/news/content/images/size/w600/2022/07/image-29.png 600w, https://www.freecodecamp.org/espanol/news/content/images/2022/07/image-29.png 1000w" sizes="(min-width: 720px) 720px" width="1000" height="462" loading="lazy"><figcaption>Deploy en GitHub Pages</figcaption></figure><p>Si tienes otro proveedor host, puedes hacer el deploy ahí. Si no tienes, y quieres algo gratuito, entonces GitHub Pages es genial!.</p><p>Primero, necesitas tener una cuenta GitHub. Si no tienes una puedes crear una cuenta <a href="https://github.com/">acá</a>.</p><p>También tienes que tener el software de control de versiones Git instalado en tu equipo. Esto es algo que cualquier desarrollador debería tener. Sin embargo, si no lo tienes, puedes instalarlo desde <a href="https://git-scm.com/downloads">acá</a>.</p><p>Lo primero que tienes que hacer es crear un nuevo repositorio en tu cuenta de GitHub:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/espanol/news/content/images/2022/07/image-30.png" class="kg-image" alt="image-30" srcset="https://www.freecodecamp.org/espanol/news/content/images/size/w600/2022/07/image-30.png 600w, https://www.freecodecamp.org/espanol/news/content/images/size/w1000/2022/07/image-30.png 1000w, https://www.freecodecamp.org/espanol/news/content/images/2022/07/image-30.png 1583w" sizes="(min-width: 720px) 720px" width="1583" height="732" loading="lazy"><figcaption>Creando un nuevo repositorio GitHub</figcaption></figure><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/espanol/news/content/images/2022/07/image-31.png" class="kg-image" alt="image-31" srcset="https://www.freecodecamp.org/espanol/news/content/images/size/w600/2022/07/image-31.png 600w, https://www.freecodecamp.org/espanol/news/content/images/size/w1000/2022/07/image-31.png 1000w, https://www.freecodecamp.org/espanol/news/content/images/2022/07/image-31.png 1583w" sizes="(min-width: 720px) 720px" width="1583" height="732" loading="lazy"></figure><p>Luego vuelve a tu terminal y ejecuta el siguiente comando:</p><!--kg-card-begin: markdown--><pre><code>npm install gh-pages --save-dev</code></pre>
<!--kg-card-end: markdown--><!--kg-card-begin: markdown--><p>Esto guardará GitHub Pages en las dependencias de tu proyecto. Si tienes problemas recuerda los flags <code>--force</code> y <code>--legacy-peer-deps</code></p>
<!--kg-card-end: markdown--><p>Una vez que hayas hecho esto, si revisas el archivo package.json. Deberías encontrar gh-page instalado de forma segura bajo devDependencies:</p><!--kg-card-begin: markdown--><pre><code>  "devDependencies": {
    "gh-pages": "^4.0.0"
  }</code></pre>
<!--kg-card-end: markdown--><p>Luego, debes seguir los siguientes 3 pasos:</p><ol><li>Navega en el directorio de tu proyecto (harperdb-movie-generator) y selecciona el archivo <code>package.json</code>. En la parte superior de tu json con paquetes, agregarás la siguiente data (reemplazala con la tuya):</li></ol><pre><code>"homepage": https://{nombre de usuario GitHub}.github.io/{nombre del proyecto}.git</code></pre><p>Para saber tu nombre de usuario y nombre de proyecto GitHub, navega al repositorio recientemente creado. En la parte superior podrás encontrar tu nombre de usuario y tu nombre de proyecto al lado. Copia ambos y llena la información en la plantilla antes mencionada.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/espanol/news/content/images/2022/07/image-32.png" class="kg-image" alt="image-32" srcset="https://www.freecodecamp.org/espanol/news/content/images/size/w600/2022/07/image-32.png 600w, https://www.freecodecamp.org/espanol/news/content/images/size/w1000/2022/07/image-32.png 1000w, https://www.freecodecamp.org/espanol/news/content/images/2022/07/image-32.png 1249w" sizes="(min-width: 720px) 720px" width="1249" height="730" loading="lazy"><figcaption>Información de GitHub para tu package.json</figcaption></figure><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/espanol/news/content/images/2022/07/image-33.png" class="kg-image" alt="image-33" srcset="https://www.freecodecamp.org/espanol/news/content/images/size/w600/2022/07/image-33.png 600w, https://www.freecodecamp.org/espanol/news/content/images/2022/07/image-33.png 733w" sizes="(min-width: 720px) 720px" width="733" height="365" loading="lazy"><figcaption>Vista del archivo package.json</figcaption></figure><p>La esencia de agregar el "homepage" es especificar el URL donde se alojará nuestra aplicación. Asegúrate de poner una coma al final, para que su package.json pueda ser analizado de forma correcta.</p><!--kg-card-begin: html--><ol>
    <li value="2">Ve al campo "scripts" dentro de `package.json` y agrega la siguiente información asegurandote de mantener la indentación de manera apropiada:
<pre><code>"predeploy": "npm run build",
"deploy": "gh-pages -d build"
</code></pre>
Esto es lo que ejecutarás cuando hagas un deploy a GitHub Pages.</li>
    <li>
        Finalmente, revisarás si tu proyecto tiene inicializado Git con el comando <code>git status</code> en la terminal estando en la raíz del proyecto. <br>
        En el caso que no retorne información del proyecto puedes iniciarlo en la terminal, estando en la raíz del proyecto, con el comando <code>git init</code>
    </li>
</ol><!--kg-card-end: html--><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/espanol/news/content/images/2022/07/image-34.png" class="kg-image" alt="image-34" srcset="https://www.freecodecamp.org/espanol/news/content/images/size/w600/2022/07/image-34.png 600w, https://www.freecodecamp.org/espanol/news/content/images/2022/07/image-34.png 981w" sizes="(min-width: 720px) 720px" width="981" height="272" loading="lazy"><figcaption>Resultado de git status</figcaption></figure><p>Te falta enlazar tu proyecto con tu repositorio GitHub. Para hacer esto debes ejecutar los siguientes comandos:</p><!--kg-card-begin: markdown--><pre><code>git branch main
git remote add origin https://github.com/{nombre de usuario}/{nombre de proyecto}.git</code></pre>
<!--kg-card-end: markdown--><h2 id="-gitignore">.gitignore</h2><p>importantísimo.</p><p>Debes modificar tu archivo .gitignore, para que no considere el archivo .env que contiene tus contraseñas al momento de hacer un commit. Para esto deberás escribir el nombre de tu archivo .env en .gitignore</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/espanol/news/content/images/2022/07/image-38.png" class="kg-image" alt="image-38" width="317" height="179" loading="lazy"></figure><!--kg-card-begin: markdown--><p>Revisemos ahora el status de tu proyecto usando el comando <code>git status</code> en la Terminal situada en la raíz de tu proyecto.</p>
<!--kg-card-end: markdown--><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/espanol/news/content/images/2022/07/image-52.png" class="kg-image" alt="image-52" srcset="https://www.freecodecamp.org/espanol/news/content/images/size/w600/2022/07/image-52.png 600w, https://www.freecodecamp.org/espanol/news/content/images/2022/07/image-52.png 928w" sizes="(min-width: 720px) 720px" width="928" height="247" loading="lazy"><figcaption>Retorno del comando git status</figcaption></figure><!--kg-card-begin: markdown--><p>En este caso podemos leer del comando que se ha modificado el archivo .gitignore, y que para agregarlo debemos usar el comando <code>git add &lt;nombre_archivo&gt;</code>, en nuestro caso sería</p>
<pre><code>git add .gitignore</code></pre>
<!--kg-card-end: markdown--><p>Esto preparará el proyecto para que tus próximos commit no tengan el archivo .env en ellos.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/espanol/news/content/images/2022/07/image-53.png" class="kg-image" alt="image-53" srcset="https://www.freecodecamp.org/espanol/news/content/images/size/w600/2022/07/image-53.png 600w, https://www.freecodecamp.org/espanol/news/content/images/2022/07/image-53.png 620w" width="620" height="158" loading="lazy"><figcaption>retorno del comando git add</figcaption></figure><!--kg-card-begin: markdown--><p>Ahora está todo configurado!</p>
<p>La única cosa que queda por hacer, es el Deploy de la app a GitHub Pages. Para hacer esto debes ejecutar el siguiente comando:</p>
<pre><code>npm run deploy</code></pre>
<!--kg-card-end: markdown--><p>y Voalá!, tu aplicación hará un deploy automático a GitHub Page</p><h2 id="como-ver-tu-aplicaci-n-en-internet">Como ver tu aplicación en internet</h2><p>Ahora tu aplicación está en internet, pero tienes que ver como es. &nbsp;Para esto debes obtener su URL.</p><p>Ve a tu perfil GitHub y haz clic en la pestaña repositorio. Selecciona tu repositorio, ve a la página configuración, y baja un poco. Encontrarás la sección GitHub Pages en la sección izquierda.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/espanol/news/content/images/2022/07/image-35.png" class="kg-image" alt="image-35" width="486" height="741" loading="lazy"></figure><!--kg-card-begin: markdown--><p>Dentro de Pages, en la sección Source, cambia a la rama <code>Branch: gh-pages</code> y selecciona la ruta <code>/root</code>. Dentro de unos minutos tu aplicación estará publicadas. Copia la URL de la página y pegala en otra pestaña del navegador.</p>
<!--kg-card-end: markdown--><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/espanol/news/content/images/2022/07/image-36.png" class="kg-image" alt="image-36" srcset="https://www.freecodecamp.org/espanol/news/content/images/size/w600/2022/07/image-36.png 600w, https://www.freecodecamp.org/espanol/news/content/images/size/w1000/2022/07/image-36.png 1000w, https://www.freecodecamp.org/espanol/news/content/images/2022/07/image-36.png 1214w" sizes="(min-width: 720px) 720px" width="1214" height="594" loading="lazy"></figure><p>Y listo, ahora verás tu proyecto en vivo (<a href="https://mauriciotrp.github.io/harperdb-movies-generator/">clic acá</a>).</p><h2 id="en-conclusi-n-">En conclusión.</h2><p>Construimos este proyecto usando React y HarperDB. HarperDB es una gran elección para que puedas manejar data y hacer operaciones Back-End.</p><p>No sólo es gratuita sino que también es muy fácil de integrar, como vimos en el tutorial.</p><p>No deberías parar acá. Puedes mejorar tus habilidades creando proyectos geniales con el mismo Stack. Gracias al plan gratuito de HarperDB no tienes que pagar nada.</p><p>Puedes tomar el código del proyecto desde éste <a href="https://github.com/MauricioTRP/harperdb-movies-generator">repositorio GitHub</a>, el repositorio original lo encuentras <a href="https://github.com/KingsleyUbah/harperdb-movie-generator">acá</a>.</p><p>Puedes ponerte en contacto con el autor original a través de <a href="https://twitter.com/ubahthebuilder">Twitter</a>. Esto es todo, gracias por seguir el tutorial hasta acá, ten una semana genial!</p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Tutorial de Async Await de JavaScript: Como esperar a que una función termine en JS ]]>
                </title>
                <description>
                    <![CDATA[ ¿Cuánto termina una función asíncrona? ¿ y porqué es una pregunta tan difícil de responder?  Resulta que para entender las funciones asincrónicas hay que tener una gran cantidad de conocimientos en JavaScript. Vamos a explorar este concepto y aprendamos un montón de JavaScript en el proceso. ¿Estás listo?, ¡vamos! ]]>
                </description>
                <link>https://www.freecodecamp.org/espanol/news/tutorial-de-async-await-de-javascript/</link>
                <guid isPermaLink="false">62ca696a771a97081f0e2dec</guid>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Mauricio Ignacio Fuentes Bravo ]]>
                </dc:creator>
                <pubDate>Mon, 18 Jul 2022 03:48:58 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/espanol/news/content/images/2022/07/5f9c987e740569d1a4ca1a5b.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artículo original:</strong> <a href="https://www.freecodecamp.org/news/async-await-javascript-tutorial/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">Async Await JavaScript Tutorial – How to Wait for a Function to Finish in JS</a>
      </p><p>¿Cuánto termina una función asíncrona? ¿ y porqué es una pregunta tan difícil de responder? </p><p>Resulta que para entender las funciones asincrónicas hay que tener una gran cantidad de conocimientos en JavaScript.</p><p>Vamos a explorar este concepto y aprendamos un montón de JavaScript en el proceso.</p><p>¿Estás listo?, ¡vamos!</p><h2 id="-qu-es-el-c-digo-as-ncrono">¿Qué es el código asíncrono?</h2><p>Por diseño, JavaScript es un lenguaje de programación sincrónico. Esto significa que, cuando el código es ejecutado, JavaScript comienza en la parte superior del archivo y ejecuta el código línea por línea hasta que termina.</p><p>El resultado de esta decisión de diseño es que sólo una cosa puede pasar en un determinado momento.</p><p>Puedes pensar en esto como si estuvieras haciendo malabares con seis pelotas pequeñas. Mientras estás haciendo malabares, tus manos están ocupadas y no puedes hacer nada más. </p><p>Es lo mismo con JavaScript: una vez que el código está corriendo, sus manos están llenas con ese código. Llamamos a este tipo de código "bloqueador". Porque está efectivamente bloqueando otro código de ser ejecutado.</p><p>Volvamos al ejemplo de los malabares. ¿Qué pasaría si quisieras agregar otra bola? En vez de seis bolas, quieres hacer malabares con siete. Esto podría ser un problema.</p><p>No quieres dejar de hacer malabares, porque estás pasándolo muy bien. Pero tampoco puedes ir a buscar otra pelota, porque significa que tendrías que parar.</p><p>¿La solución? Delegar el trabajo a un amigo o miembro de la familia. Ellos no están haciendo malabares por lo que pueden ir a buscar otra pelota para ti, y luego lanzarla justo en el momento en que tengas una mano libre para agregar una nueva pelota a los malabares.</p><p>Así son los códigos asíncronos. JavaScript está delegando el trabajo a otra cosa, y luego se encarga de sus asuntos. Luego, cuando esté listo, recibirá los resultados del trabajo.</p><h2 id="-qui-n-est-haciendo-el-otro-trabajo">¿Quién está haciendo el otro trabajo?</h2><p>Bueno, sabemos que JavaScript es sincrónico y flojo. No quiere hacer todo el trabajo por si mismo, por lo que lo distribuye tareas a otra cosa. </p><p>¿Pero quién es esta misteriosa entidad que trabaja para JavaScript? ¿ Y como es contratado para trabajar para JavaScript?</p><p>Bueno, miremos un ejemplo de código asíncrono. </p><!--kg-card-begin: markdown--><pre><code>const logName = () =&gt; {
    console.log("Han")
}

setTimeout(logName,0)

console.log("Hola!!")</code></pre>
<!--kg-card-end: markdown--><p>Al correr este código, aparece el siguiente resultado en la consola:</p><!--kg-card-begin: markdown--><pre><code>// En la consola
Hola!!
Han</code></pre>
<!--kg-card-end: markdown--><p>Ok, ¿Qué está pasando?</p><p>Resulta que la forma en que trabajamos en JavaScript es usando funciones específicas del entorno y APIs, y es una fuente de gran confusión. </p><p><strong>JavaScript siempre se ejecuta en un entorno.</strong></p><p>A menudo este entorno es el navegador. Pero también puede ejecutarse en el servidor con NodeJS. Pero ¿Cuál es la diferencia? </p><p>La diferencia - y es importante - es que el navegador y el servidor (NodeJS), en cuanto a funcionalidad, no son equivalentes. A menudo son similares, pero no son lo mismo.</p><p>Ilustremos esto con un ejemplo. Digamos que JavaScript es el protagonista de un épico libro de fantasía. Solo un niño común de campo.</p><p>Ahora digamos que este niño campesino encontró dos armaduras especiales que le dan poderes por sobre su conocimiento.</p><p>Cuando usa la armadura "Navegador", obtiene acceso a un cierto conjunto de habilidades.</p><p>Cuando usa la armadura "Servidor", obtiene acceso a otro conjunto de habilidades.</p><p>Estos trajes tienen algunas superposiciones, porque los creadores de estos trajes tuvieron las mismas necesidades en determinados lugares, pero no en otros.</p><p>Esto es un entorno. Un lugar donde el código ejecuta, donde existen herramientas que están hechas sobre el lenguaje existente JavaScript. Estos no son parte del lenguaje, pero la línea divisoria es a menudo borrosa, porque utilizamos estas herramientas todos los días cuando escribimos código.</p><p><a href="https://developer.mozilla.org/es/docs/Web/API/setTimeout">setTimeout</a>, <a href="https://developer.mozilla.org/es/docs/Web/API/Fetch_API">fetch</a> y <a href="https://developer.mozilla.org/es/docs/Web/API/Document_Object_Model">DOM</a> son ejemplos de APIs Web (Puedes ver la<a href="https://developer.mozilla.org/es/docs/Web/API"> lista completa de APIs Web</a> aquí). Estas son herramientas que están construidas sobre el navegador, y están disponibles para nosotros cuando el código es ejecutado.</p><p>Y como siempre ejecutamos JavaScript en un entorno, pareciera que estas son parte del lenguaje, Pero no lo son. </p><p>Por lo que si alguna vez te preguntaste por qué puedes usar fetch en JavaScript cuando lo ejecutas en el navegador (pero necesitas instalar un paquete cuando lo ejecutas en NodeJS), este es el porqué. Alguien pensó que fetch era una buena idea, y creó una herramienta para el entorno NodeJS.</p><p>¿Confuso?, si! </p><p>Ahora finalmente podemos entender qué cosa hace el trabajo de JavaScript y como JavaScrip lo contrata para hacerlo.</p><p>Resulta que es el entorno el que hace el trabajo, y la forma en que el entorno hace el trabajo es usando las funcionalidades que pertenecen al entorno. Por ejemplo <em>fetch</em> o <em>setTimeout</em> en el entorno del navegador.</p><h2 id="-qu-le-pasa-al-trabajo">¿Qué le pasa al trabajo?</h2><p>Excelente, así que el entorno hace el trabajo, ¿ y luego qué?</p><p>En algún punto necesitas obtener los resultados de vuelta. Pero pensemos sobre como esto funcionaría.</p><p>Volvamos al ejemplo de los malabares del principio. Imagina que pediste una nueva pelota, y un amigo comenzó a tirarte pelotas cuando no estabas listo.</p><p>Esto sería un desastre. Tal vez tuviste suerte de agarrarlas y meterlas en tu rutina de manera efectiva. Pero existe una gran probabilidad de que se te caigan las pelotas y arruine tu rutina. ¿No sería mejor si das instrucciones estrictas sobre cuando recibir el balón?</p><p>Resulta que existen reglas estrictas sobre cuando JavaScript puede recibir el trabajo delegado.</p><p>Estas reglas están gobernadas por el <em>Event Loop</em> e involucra la lista de micro y macro tareas. Si sé, es mucho. Pero tenme paciencia.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/espanol/news/content/images/2022/07/image-6.png" class="kg-image" alt="image-6" srcset="https://www.freecodecamp.org/espanol/news/content/images/size/w600/2022/07/image-6.png 600w, https://www.freecodecamp.org/espanol/news/content/images/size/w1000/2022/07/image-6.png 1000w, https://www.freecodecamp.org/espanol/news/content/images/2022/07/image-6.png 1272w" sizes="(min-width: 720px) 720px" width="1272" height="681" loading="lazy"></figure><p>Ok, cuando delegamos código asincrónico al navegador, el navegador toma y ejecuta el código y se encarga de esa carga de trabajo. Pero tal vez hay muchas tareas que se dan al navegador, por lo que necesitamos asegurarnos de que podemos priorizar estas tareas.</p><p>Aquí es donde la lista de microtareas y macrotareas entran al juego. El navegador toma el trabajo, lo hace, y luego coloca el resultado en una de estas dos listas basado en el tipo de trabajo que recibe.</p><p>Las promises, por ejemplo, son colocadas en la lista de microtareas y tienen una prioridad mayor.</p><p>Eventos y setTimeout son ejemplos de trabajos que se colocan en la lista de macrotareas, y tienen menor prioridad.</p><p>Ahora, una vez que el trabajo está listo y es colocado en alguna de estas dos listas, el<em> Event Loop</em> ejecutará en ambas direcciones un chequeo para revisar si JavaScript está listo o no para recibir estos resultados.</p><p>Sólo cuando JavaScript terminó de ejecutar su código sincrónico, y está preparado, el <em>Event Loop</em> comenzará a tomar de las listas (microtareas y macrotareas) y devolverá las funciones para que JavaScript las ejecute.</p><p>Miremos un ejemplo:</p><!--kg-card-begin: markdown--><pre><code>setTimeout( () =&gt; console.log("Hola"),0)

fetch("https://algunAPI/data").then(response =&gt; response.json())
                              .then(data =&gt; console.log(data))

console.log("Que pasa?")</code></pre>
<!--kg-card-end: markdown--><p>¿Cuál sería el orden acá?</p><!--kg-card-begin: markdown--><ol>
<li>Primeramente, setTimeout es delegado al navegador, el cual hace el trabajo y coloca el resultado de la función en la lista de macrotareas.</li>
<li>En segundo lugar, fecth es delegado al navegador, el cual toma el trabajo. Este recibe la data desde el endpoit y coloca las funciones resultantes en la lista de microtareas.</li>
<li>JavaScript pone en console "Que pasa?"</li>
<li>El Event Loop revisa si JavaScript está listo o no para recibir el resultado de las listas de tareas</li>
<li>Cuando el console.log está listo, JavaScript está listo. El Event Loop toma la función en la lista de microtareas, la cual tiene una mayor prioridad, y se la da a JavaScript para ejecutarla.</li>
<li>Después de que la lista de microtareas está vacía, el callback setTimeout es sacado de la lista de macrotareas y se pasa a JavaScript para ser ejecutado.</li>
</ol>
<pre><code>En la consola: 
// Que pasa?
// La data del API
// Hola</code></pre>
<!--kg-card-end: markdown--><h2 id="promesas">Promesas</h2><p>Ahora deberías tener una buena cantidad de conocimiento acerca de cómo el código asíncrono es manejado por JavaScript en el entorno del Navegador. Así que hablemos de las promesas.</p><p>Una promesa es un constructo en JavaScript que representa un valor futuro desconocido. Conceptualmente una promesa es sólo JavaScript prometiendo retornar un valor. Este puede ser el resultado de la llamada a un API, o puede ser un objeto error de una solicitud de red fallida. Estás garantizado que recibirás algo.</p><!--kg-card-begin: markdown--><pre><code>const promise = new Promise((resolve, reject) =&gt; {
    // Hace una nueva solicitud de red
    if ( response.status === 200) {
        resolve(response.body)
    } else {
        const error = { ... }
        reject(error)
    }
})

promise.then(res =&gt; {
    console.log(res)
}).catch(err =&gt; {
    console.log(err)
})</code></pre>
<!--kg-card-end: markdown--><p>Una promesa puede tener los siguientes estados:</p><!--kg-card-begin: markdown--><ul>
<li>Cumplida (fulfilled) - acción completada satisfactoriamente</li>
<li>Rechazada (rejected) - acción fallida</li>
<li>Pendiente (pending) - ninguna de las acciones ha sido completada</li>
<li>Establecida (settled) - ha sido cumplida o rechazada</li>
</ul>
<!--kg-card-end: markdown--><p>Una promesa recibe una función resolve y una reject, que pueden ser llamadas para gatillar alguno de estos estados.</p><p>Uno de los puntos fuertes de las promesas es que podemos encadenar funciones que queremos que ocurran en el caso de éxito (resolve) o de falla (reject):</p><!--kg-card-begin: markdown--><ul>
<li>Para registrar una función que se ejecute en caso de éxito usamos <code>.then</code></li>
<li>para registrar una función que se ejecute en caso de fallo usamos <code>.catch</code></li>
</ul>
<!--kg-card-end: markdown--><!--kg-card-begin: markdown--><pre><code>// Fetch retorna una promesa
fetch("https://swapi.dev/api/people/1")
    .then((res) =&gt; console.log("Esta función es retornada cuando la solicitud es exitosa",res))
    .catch(err =&gt; console.log("Esta función es retornada cuando la solicitud es fallida", err))
    
// Encadenando multiples funciones
fetch("https://swapi.dev/api/people/1")
    .then((res) =&gt; hazAlgoConElResultado(res))
    .then((resultadoFinal) =&gt; console.log(resultadoFinal))
    .catch((err =&gt; hazAlgoConElError(err) )</code></pre>
<!--kg-card-end: markdown--><p>Perfecto!, ahora demos una mirada más cerca a como se ven las cosas bajo el capó usando fetch como ejemplo:</p><!--kg-card-begin: markdown--><pre><code>const fetch = (url , options) =&gt; {
    // simplificado
    return new Promise((resolve, reject) =&gt; {
    
    const xhr = new XMLHttpRequest()
    // ... hace una solicitud
    xhr.onload = () =&gt; {
        const options = {
            status: xhr.status,
            statusText: xhr.statusText
            ...
        }
        
        resolve(new Response(xhr.response, options))
    }
    
    xhr.onerror = () =&gt; {
        reject( new TypeError("Solicitud fallida"))
    }
}

fetch("https://swapi.dev/api/people/1")
    // registra handleResponse para ejecutar cuando la promesa se resuelve
    .then(handleResponse)
    .catch(handleError)
    
// conceptualmente la promesa se ve de esta manera ahora: 
// {status: "pending", casoExito: [handleResponse], casoFallo: [handleError]}
    
const handleResponse = (response) =&gt; {
    // handleResponse recibirá automáticamente la respuesta porque la promesa
    // resuelve con un valor y automáticamente la inyecta a la función
    console.log(response)
}

const handleError = (response) =&gt; {
    // handleError recibirá automáticamente el error porque la promesa 
    // resuelve con un valor y automáticamente la inyecta a la función
    console.log(response)
}

// la promesa resolverá o rechazará haciendo que ejecute todas las funciones 
// registradas en los arrays respectivos inyectando el valor.
// Inspeccionemos el recorrido:

// 1. el evento de escucha XHR se dispara.
// 2. Si la respuesta es exitosa, el evento de escucha onload se gatilla
// 3. onload dispara la función resolve(VALOR) con un valor dado
// 4. resolve gatilla y organiza las funciones registradas con .then </code></pre>
<!--kg-card-end: markdown--><p>Entonces, podemos usar promesas para hacer trabajo asíncrono, y para asegurarnos que podemos manejar cualquier resultado de esas promesas. Esta es la propuesta de valor. Si quieres saber más sobre las promesas puedes leer sobre ellas <a href="https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Global_Objects/Promise">aquí</a> y <a href="https://web.dev/promises/">aquí</a></p><p>Cuando usamos promesas, encadenamos nuestras funciones a la promesa para manejar distintos escenarios.</p><p>Esto funciona, pero todavía tenemos que manejar nuestra lógica dentro de los callbacks (funciones anidadas) una vez que obtenemos nuestros resultados de vuelta). Qué tal si pudiéramos usar promesas pero escribir código que parezca sincrónico? resulta que podemos </p><h2 id="async-await">Async/Await</h2><p>Async/Await es una forma de escribir promesas que nos permite escribir código asincrónico, pero de manera sincrónica. Demos una mirada.</p><!--kg-card-begin: markdown--><pre><code>const obtenerData = async () =&gt; {
    const response = await fetch("https://jsonplaceholder.typicode.com/todos/1")
    const data = await response.json()
   
   console.log(data)
}

obtenerData()</code></pre>
<!--kg-card-end: markdown--><p>Aquí, nada ha cambiado bajo el capó. Seguimos usando promesas para obtener la data, pero ahora parece sincrónico, y ya no tiene los bloques .then y .catch.</p><p>Async/Await realmente es sólo azúcar sintáctica que provee una forma de crear código más fácil de razonar, sin cambiar la dinámica subyacente.</p><p>Miremos como trabaja.</p><p>Async/Await nos deja usar <a href="https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Global_Objects/Generator">generadores</a> para <em>pausar</em> la ejecución de una función. Cuando usas async/await no estas bloqueando porque la función está devolviendo el control al programa principal.</p><p>Luego cuando la promesa resuelve estamos usamos el generador para devolver el control a la función asincrónica con el valor de la promesa resuelta.</p><p><a href="https://github.com/getify/You-Dont-Know-JS/blob/1st-ed/async%20%26%20performance/ch4.md">Puedes leer más acá para tener una excelente descripción</a> general sobre generadores y código asincrónico.</p><p>En efecto, podemos ahora escribir código asíncrono como sin fuera sincrónico. Lo que significa que es más fácil razonarlo, y podemos usar herramientas sincrónicas para manejo de errores como try/catch:</p><!--kg-card-begin: markdown--><pre><code>const obtenerData = async () =&gt; {
    try {
        const respuesta = await fetch("https://jsonplaceholder.typicode.com/todos/1")
        const data = await respuesta.json()
        console.log(data)
    } catch (err) {
        console.log(err)
    }
}

obtenerData()</code></pre>
<!--kg-card-end: markdown--><p>Ok, ¿Ahora como lo usamos? Para usar async/await debemos anteponer la función async. Esto no la convierte en una función asíncrona, simplemente nos deja usar await dentro de ella.</p><p>Si no se usa la palabra clave async tendremos un error sintáctico (syntax error) cuando tratemos de usarla dentro de una función regular.</p><!--kg-card-begin: markdown--><pre><code>const obtenerData = async() =&gt; {
    console.log("Ahora podemos usar await en esta función")
}</code></pre>
<!--kg-card-end: markdown--><p>Es por esto que no podemos usar async/await en código de alto nivel. Pero async/await siguen siendo sólo azúcar sintáctica sobre promesas. Así podemos manejar casos de alto nivel con encadenamiento de promesas:</p><!--kg-card-begin: markdown--><pre><code>async function obtenerData() {
    let respuesta = await fetch('https://apiurl.com');
}

// obtenerData es una promesa
obtenerData().then(res =&gt; console.log(res)).catch(err =&gt; console.log(err);</code></pre>
<!--kg-card-end: markdown--><p>Esto muestra otro aspecto interesante acerca de async/await. Cuando definimos una función como async, <em><strong>esta siempre retorna una promesa.</strong></em></p><p>Usar async/await puede parecer magia en un comienzo. Pero como cualquier magia, es sólo tecnología lo suficientemente avanzada que ha evolucionado a través de los años. Esperemos que ahora tengas un comprensión sólida de los fundamentos, y puedas usar async/await con confianza.</p><h2 id="conclusi-n">Conclusión</h2><p>Si llegaste hasta acá, felicidades!. Recién agregaste una pieza muy importante sobre JavaScript y como este funciona con su entorno a tu caja de herramientas.</p><p>Este definitivamente es un tema confuso, y las líneas no son siempre claras. Pero espero que ahora tengas una idea de como JavaScript funciona con código asíncrono en el navegador, y un entendimiento más fuerte sobre promesas y async/await.</p><p>Si disfrutaste este artículo, talvez disfrutes también el <a href="https://www.youtube.com/channel/UCZTeUahnA2GMoo_YpTBFo9A?view_as=subscriber">canal de youtube del autor (inglés)</a>. Actualmente tiene una serie sobre fundamentos web, donde revisa aspectos como <a href="https://www.youtube.com/watch?v=0ykAOzJb-U8&amp;t=19s">HTTP</a>, <a href="https://www.youtube.com/watch?v=R5uwuG1wPR8">construcción de servidores web desde cero</a> y mas.</p><p>Gracias por leer!</p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Lista de códigos de teclas en JavaScript: Códigos de eventos de teclado para enter, espacio, retroceso y más ]]>
                </title>
                <description>
                    <![CDATA[ Los eventos de teclado te ayudan a capturar las interacciones del usuario con el teclado. Como muchos otros eventos en JavaScript, la interface KeyboardEvent provee todas las propiedades y métodos requeridas para manejar cada pulsión de tecla que el usuario haga en el teclado. Ha habido muchos artículos escritos acerca ]]>
                </description>
                <link>https://www.freecodecamp.org/espanol/news/lista-de-codigos-de-teclas-en-javascript/</link>
                <guid isPermaLink="false">62befa7bc5b22c08edf8d0c1</guid>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Mauricio Ignacio Fuentes Bravo ]]>
                </dc:creator>
                <pubDate>Fri, 15 Jul 2022 21:28:19 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/espanol/news/content/images/2022/07/freeCodeCamp-Cover.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artículo original:</strong> <a href="https://www.freecodecamp.org/news/javascript-keycode-list-keypress-event-key-codes/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">JavaScript Keycode List – Keypress Event Key Codes for Enter, Space, Backspace, and More</a>
      </p><p>Los eventos de teclado te ayudan a capturar las interacciones del usuario con el teclado.</p><!--kg-card-begin: markdown--><p>Como muchos otros eventos en JavaScript, la interface <code>KeyboardEvent</code> provee todas las propiedades y métodos requeridas para manejar cada pulsión de tecla que el usuario haga en el teclado.</p>
<!--kg-card-end: markdown--><p>Ha habido muchos artículos escritos acerca de como funcionan y como usarlos. Al mismo tiempo, <a href="https://www.w3.org/TR/uievents/#events-keyboardevents">W3.org</a> se mantiene actualizando las especificaciones, introduciendo nuevas propiedades, y dejando obsoletas algunas existentes, y etiquetando cierto código como antiguo.</p><!--kg-card-begin: markdown--><p>Producto de esto, es esencial para el desarrollador web mantenerse aprendiendo sobre la interface <code>KeyboardEvent</code> para saber exactamente qué usar y qué dejó de ser relevante.</p>
<!--kg-card-end: markdown--><p>En este artículo aprenderás sobre: </p><!--kg-card-begin: markdown--><ul>
<li>La interface KeyboardEvent.</li>
<li>Los tipos de eventos de teclado (keyboard event types) en los que necesitamos enfocarnos.</li>
<li>Los tipos de eventos de teclado que tal vez nunca necesitemos.</li>
<li>Qué propiedades necesitas en la práctica y cómo los diferentes navegadores las manejan.</li>
<li>Qué está obsoleto, y qué está en uso.</li>
<li>Un lugar para probar esto mientras aprendemos</li>
<li>Finalmente, la lista actual de key codes para referencia y uso futuro.</li>
</ul>
<!--kg-card-end: markdown--><p>Espero que lo disfrutes.</p><h2 id="la-interfaz-keyboardevent-y-los-tipos-de-eventos">La interfaz KeyboardEvent y los tipos de eventos</h2><!--kg-card-begin: markdown--><p>La interfaz KeyboardEvent provee información usando las constantes, propiedades y un único método definidos (a partir de enero de 2021). Esta extiende la interfaz <code>UIEvent</code> la cual eventualmente extiende la interfaz <code>Event</code>.</p>
<!--kg-card-end: markdown--><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/espanol/news/content/images/2022/07/image-1.png" class="kg-image" alt="image-1" srcset="https://www.freecodecamp.org/espanol/news/content/images/size/w600/2022/07/image-1.png 600w, https://www.freecodecamp.org/espanol/news/content/images/2022/07/image-1.png 900w" sizes="(min-width: 720px) 720px" width="900" height="500" loading="lazy"><figcaption>Jerarquía KeyboardEvent</figcaption></figure><!--kg-card-begin: markdown--><p>Hay principalmente tres tipos de eventos de teclado: <code>keydown</code>, <code>keypress</code> y <code>keyup</code>. Podemos obtener información contextual de estos eventos de las propiedades y métodos de la interfaz <code>KeyboardEvent</code>.</p>
<!--kg-card-end: markdown--><!--kg-card-begin: markdown--><p>Puedes agregar cada uno de estos tipos de eventos a un elemento HTML o <code>document</code> object usando el método <code>addEventListener</code>. Aquí hay un ejemplo de escucha a un evento <code>keydown</code> en un elemento cuyo id es "escribe-aqui":</p>
<!--kg-card-end: markdown--><!--kg-card-begin: markdown--><pre><code>let elem = document.getElementById('escribe-aqui');

elem.addEventListener("keydown", function (event) {
    // El parámetro del evento es del tipo KeyboardEvent
  	addRow(event);
});</code></pre>
<!--kg-card-end: markdown--><!--kg-card-begin: markdown--><p>De forma alternativa, puedes usar métodos de manipulación como <code>onKeydown(event)</code>, <code>onKeyup(event)</code>, <code>onKeyPress(event)</code> con el elemento para manejar eventos de teclado. Aquí hay un ejemplo de manejo de un evento <code>keyup</code> a un elemento input:</p>
<!--kg-card-end: markdown--><!--kg-card-begin: markdown--><pre><code>&lt;input type="text" id="escribe-aqui" onkeyup="hazAlgo(event)"&gt;</code></pre>
<!--kg-card-end: markdown--><!--kg-card-begin: markdown--><p>Si imprimes el objeto <code>event</code> en la consola del navegador, verás todas sus propiedades y métodos junto con los que hereda de las interfaces <code>UIEvent</code> y <code>Event</code>.</p>
<!--kg-card-end: markdown--><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/espanol/news/content/images/2022/07/image-2.png" class="kg-image" alt="image-2" srcset="https://www.freecodecamp.org/espanol/news/content/images/size/w600/2022/07/image-2.png 600w, https://www.freecodecamp.org/espanol/news/content/images/2022/07/image-2.png 777w" sizes="(min-width: 720px) 720px" width="777" height="772" loading="lazy"><figcaption>Presioné la tecla a, mientras el keyup event está escuchando</figcaption></figure><h2 id="prueba-este-juego-evento-de-teclado-interactivo">Prueba este juego evento de teclado interactivo</h2><p>Antes de avanzar, ¿qué te parece un juego para explorar los eventos de teclado, sus propiedades, características y más? Creo que sería increíble usarlo junto con este artículo y más allá. </p><figure class="kg-card kg-embed-card"><iframe src="https://stackblitz.com/edit/web-platform-p9rert?embed=1&amp;file=script.js&amp;view=preview" height="400" width="745" title="Contenido incrustado" loading="lazy"></iframe></figure><blockquote>Si tienes problemas para acceder al juego de arriba, puedes acceder a la herramienta directamente aquí: <a href="https://mauriciotrp.github.io/KeyboardEvents/">https://mauriciotrp.github.io/KeyboardEvents/</a><br><br>y puedes acceder al código fuente del demo aquí:<br><a href="https://github.com/MauricioTRP/KeyboardEvents">https://github.com/MauricioTRP/KeyboardEvents</a></blockquote><h2 id="keydown-keypress-keyup-cu-l-deber-a-usar">keydown, keypress, keyup - ¿Cuál debería usar?</h2><p>Los eventos de teclado son:</p><!--kg-card-begin: markdown--><ul>
<li><code>keydown</code>: este se dispara cuando una tecla es presionada.</li>
<li><code>keypress</code>: esta sólo se dispara cuando una tecla que produce un <a href="https://www.w3.org/TR/uievents/#character-value">valor de caracter</a> es presionada. Por ejemplo, si aprietas la tecla <code>a</code>, este evento se disparará cuando la tecla <code>a</code>produzca el valor de caracter <code>97</code>. Por otra parte, este evento no se disparará cuando aprietes la tecla <code>Shift</code> ya que esta no produce un valor de caracter.</li>
<li><code>keyup</code>: este se dispara cuando una tecla es "liberada"</li>
</ul>
<!--kg-card-end: markdown--><p>Si estos tres eventos se adjuntan a un elemento del DOM, el orden de ejecución sería: </p><!--kg-card-begin: markdown--><ol>
<li>Primero, <code>keydown</code></li>
<li>Luego, <code>keypress</code> (con la condición declarada arriba)</li>
<li>Último, <code>keyup</code></li>
</ol>
<!--kg-card-end: markdown--><!--kg-card-begin: markdown--><p>Entre estos eventos, el más usado (o debería ser) es <code>keydown</code> porque:</p>
<ul>
<li>El evento <code>keydown</code> tiene la covertura más amplia de teclas que producen información contextual. El evento <code>keypress</code> funciona sólo con un subconjunto de teclas. No puedes capturar Alt, Ctrl, Meta y otros eventos de teclas similares con keypress. Esto también significa que no puedes disparar el evento keypress con combinaciones de teclas como <code>Ctrl Z</code>, <code>Shift Tab</code> y así.</li>
<li>Más aún, <a href="https://www.w3.org/TR/uievents/#event-type-keypress">el evento <code>keypress</code></a> ha quedado obsoleto. Esta es una razón lo suficientemente fuerte para evitarlo.</li>
<li>Mientras que <code>keydown</code> y <code>keyup</code> son eventos que cubren todas las teclas y están bien soportados por la mayoría de los navegadores, hay algunas diferencias que hacen preferir <code>keydown</code> sobre <code>keyup</code>. Los eventos keydown se disparan después que el navegador procesa la tecla. Si tu cancelas un evento keydown (por ejemplo usando <code>event.preventDefault()</code>), la acción del navegador será cancelada también. En el caso del evento keyup, la acción del navegador no será cancelada cuando hayas cancelado el evento.</li>
</ul>
<!--kg-card-end: markdown--><!--kg-card-begin: markdown--><p>En el ejemplo de abajo, estamos usando <code>event.preventDefault()</code>cuando un evento <code>keydown</code> o <code>keyup</code> se dispara. La acción del navegador de escribir el caracter de la tecla no será realizado en el caso de <code>keydown</code> pero si ocurrirá en el caso de <code>keyup</code>.</p>
<!--kg-card-end: markdown--><!--kg-card-begin: markdown--><p>Con toda esa explicación el evento <code>keydown</code> es el ganador indiscutiro y debería convertirse en el tipo de evento más popular (usado)</p>
<!--kg-card-end: markdown--><figure class="kg-card kg-embed-card"><iframe src="https://stackblitz.com/edit/web-platform-91rgfu?devToolsHeight=33&amp;embed=1&amp;file=index.html" height="400" width="745" title="Contenido incrustado" loading="lazy"></iframe></figure><h2 id="como-usar-las-propiedades-del-keyboardevent-en-la-pr-ctica">Como usar las propiedades del KeyboardEvent en la práctica</h2><p>¡Esta es la pregunta del billón de dólares! La respuesta corta es "depende", pero ¿de qué? Depende de: </p><!--kg-card-begin: markdown--><ul>
<li>Que el navegador soporte tu aplicación</li>
<li>Cuan antigua es el código de tu aplicación, y cuanto estás dispuesto a refactorizar?</li>
</ul>
<!--kg-card-end: markdown--><!--kg-card-begin: markdown--><p>Pero antes que lleguemos ahí, veamos un adelanto de algunas propiedades y metodos útiles del interface <code>KeyboardEvent</code></p>
<!--kg-card-end: markdown--><!--kg-card-begin: html--><table>
    <tbody><tr>
        <th>PROPIEDAD/MÉTODO</th>
        <th>DESCRIPCIÓN</th>
        <th>OBSOLETA (deprecated)</th>
    </tr>
    <tr>
        <td>altKey</td>
        <td>Retorna un booleano (True/False). El valor es <code>true</code>cuando la tecla <kbd>Alt</kbd> es presionada</td>
        <td>No</td>
    </tr>
    <tr>
        <td>ctrlKey</td>
        <td>Retorna un booleano (True/False). El valor es <code>true</code> cuando la tecla <kbd>Ctrl</kbd> es presionada</td>
        <td>No</td>
    </tr>
    <tr>
        <td>shiftKey</td>
        <td>Retorna un booleano (True/False). El valor es <code>true</code> cuando la tecla <kbd>Shift</kbd> es presionada</td>
        <td>No</td>
    </tr>
    <tr>
        <td>metaKey</td>
        <td>Retorna un booleano (True/False). El valor es <code>true</code> cuando cualquiera de las teclas <kbd>Meta</kbd> es presionada</td>
        <td>No</td>
    </tr>
    <tr>
        <td>code</td>
        <td>El código de la tecla física</td>
        <td>No</td>
    </tr>
    <tr>
        <td>key</td>
        <td>la tecla que está siendo presionada</td>
        <td>No</td>
    </tr>
    <tr>
        <td>metodo getModifierState()</td>
        <td>Retorna un booleano (True/False). El valor <code>true</code> indica el estado <code>on</code> de las siguientes teclas <kbd>CapsLock</kbd>,<kbd>NumLock</kbd>,<kbd>Alt</kbd>,<kbd>Control</kbd>,<kbd>Shift</kbd>,<kbd>Meta</kbd>,etc </td>
        <td>No</td>
    </tr>    
    <tr>
        <td>charCode</td>
        <td>Retorna el valor Unicode. Este se ha dejado obsoleto y deberíamos usar la propiedad <code>key</code> en su lugar.</td>
        <td>Si</td>
    </tr>
    <tr>
        <td>keyCode</td>
        <td>Retorna el código numérico del valor presionado. Este se ha dejado obsoleto y deberíamos usar la propiedad <code>key</code> en su lugar.</td>
        <td>Si</td>
    </tr>
    <tr>
        <td>wich</td>
        <td>Retorna el código numérico del valor presionado. Este se ha dejado obsoleto y deberíamos usar la propiedad <code>key</code> en su lugar.</td>
        <td>Si</td>
    </tr>
</tbody></table><!--kg-card-end: html--><!--kg-card-begin: markdown--><p>Las últimas tres propiedades han quedado obsoletas y deberías usar la propiedad <code>key</code> en su lugar. La propiedad <code>key</code> es la que <a href="https://caniuse.com/?search=Keyboardevent.key">tiene mayor soporte de navegadores.</a></p>
<p>Está soportada en:</p>
<ul>
<li>Microsoft Edge: Versión &gt;=79</li>
<li>Firefox: Versión &gt;=29</li>
<li>Google Chrome: Versión &gt;=51</li>
<li>Safari: Versión &gt;=10.1</li>
</ul>
<p>Entonces, mientras no uses ninguno de los navegadores más antiguos, la propiedad <code>event.key</code> debería ser suficiente para que puedas identificar una tecla. En el caso que tengas que dar soporte a navegadores más antiguos, una mejor alternativa sería la propiedad <code>event.which</code></p>
<!--kg-card-end: markdown--><!--kg-card-begin: markdown--><pre><code>window.addEventListener("keydown", function(event) {

    if(event.key !== undefined) {
        // Manipula el evento con KeyboardEvent.key
    } else if (event.wich !== undefined) {
        // Manipula el evento con KeyboardEvent.wich
    }
});</code></pre>
<!--kg-card-end: markdown--><p>Si tu código usa cualquiera de estas propiedades obsoletas y tienes la oportunidad de refactorizar este código, lo mejor es hacerlo.</p><h2 id="teclas-modificadoras">Teclas Modificadoras</h2><!--kg-card-begin: html--><p>Las teclas modificadoras son las teclas especiales en tu teclado que modifican el comportamiento por defecto de las otras teclas. <kbd>Control</kbd>, <kbd>Shift</kbd>, y <kbd>Alt</kbd> son algunas modificadoras. Cuando una tecla modificadora es combinada con otra tecla, puedes esperar que una acción distinta ocurra.
</p>
<p>Por ejemplo, si tu aprietas la tecla <kbd>z</kbd>, se supone que retorna el código o la letra z. Pero si la combinas con la modificadora <kbd>Control</kbd> y presionas <kbd>Ctrl</kbd>+<kbd>z</kbd>, lo más probable es que tengas la operación <code>deshacer</code>. Veámoslo con más ejemplos en la próxima sección
</p><!--kg-card-end: html--><!--kg-card-begin: markdown--><p>Las propiedades, <code>event.altKey</code>,  <code>event.ctrlKey</code>, <code>event.shiftKey</code> y así. Ayudan a detectar si una tecla modificadora ha sido presionada.</p>
<!--kg-card-end: markdown--><h2 id="combinaci-n-de-teclas">Combinación de teclas</h2><!--kg-card-begin: html--><p>Podemos combinar múltiples teclas y realizar acciones basandonos en las combinaciones. El code snippet de más abajo muestra como combinar la tecla <kbd>Ctrl</kbd> y <kbd>Z</kbd> para definir una acción:</p><br><!--kg-card-end: html--><!--kg-card-begin: markdown--><pre><code>document
    .getElementById("to_focus")
    .addEventListener("keydown", function(event) {
    	if(event.ctrlKey &amp;&amp; event.key === "z"){
    		// Hacer algo, tal vez deshacer
    	}
    }
});</code></pre>
<!--kg-card-end: markdown--><p>Aquí hay otro ejemplo que demuestra algo más sobre combinación de teclas:</p><figure class="kg-card kg-embed-card kg-card-hascaption"><iframe src="https://stackblitz.com/edit/web-platform-o1fobp?embed=1&amp;file=styles.css&amp;view=preview" height="400" width="745" title="Contenido incrustado" loading="lazy"></iframe><figcaption>Prueba las combinaciones de teclas</figcaption></figure><h2 id="una-lista-completa-de-los-valores-de-eventos-de-teclas-">Una lista completa de los valores de eventos de teclas.</h2><!--kg-card-begin: markdown--><p>La tabla de más abajo muestra una lista de teclas con los valores de <code>event.which</code>, <code>event.key</code> y <code>event.code</code></p>
<!--kg-card-end: markdown--><!--kg-card-begin: html--><table>
<thead>
<tr>
<th>Key Name</th>
<th>event.which</th>
<th>event.key</th>
<th>event.code</th>
<th>Notes</th>
</tr>
</thead>
<tbody>
<tr>
<td>backspace</td>
<td>8</td>
<td>Backspace</td>
<td>Backspace</td>
<td></td>
</tr>
<tr>
<td>tab</td>
<td>9</td>
<td>Tab</td>
<td>Tab</td>
<td></td>
</tr>
<tr>
<td>enter</td>
<td>13</td>
<td>Enter</td>
<td>Enter</td>
<td></td>
</tr>
<tr>
<td>shift(left)</td>
<td>16</td>
<td>Shift</td>
<td>ShiftLeft</td>
<td><code>event.shiftKey</code> is true</td>
</tr>
<tr>
<td>shift(right)</td>
<td>16</td>
<td>Shift</td>
<td>ShiftRight</td>
<td><code>event.shiftKey</code> is true</td>
</tr>
<tr>
<td>ctrl(left)</td>
<td>17</td>
<td>Control</td>
<td>ControlLeft</td>
<td><code>event.ctrlKey</code> is true</td>
</tr>
<tr>
<td>ctrl(right)</td>
<td>17</td>
<td>Control</td>
<td>ControlRight</td>
<td><code>event.ctrlKey</code> is true</td>
</tr>
<tr>
<td>alt(left)</td>
<td>18</td>
<td>Alt</td>
<td>AltLeft</td>
<td><code>event.altKey</code> is true</td>
</tr>
<tr>
<td>alt(right)</td>
<td>18</td>
<td>Alt</td>
<td>AltRight</td>
<td><code>event.altKey</code> is true</td>
</tr>
<tr>
<td>pause/break</td>
<td>19</td>
<td>Pause</td>
<td>Pause</td>
<td></td>
</tr>
<tr>
<td>caps lock</td>
<td>20</td>
<td>CapsLock</td>
<td>CapsLock</td>
<td></td>
</tr>
<tr>
<td>escape</td>
<td>27</td>
<td>Escape</td>
<td>Escape</td>
<td></td>
</tr>
<tr>
<td>space</td>
<td>32</td>
<td></td>
<td>Space</td>
<td>The <code>event.key</code> value is a single space.</td>
</tr>
<tr>
<td>page up</td>
<td>33</td>
<td>PageUp</td>
<td>PageUp</td>
<td></td>
</tr>
<tr>
<td>page down</td>
<td>34</td>
<td>PageDown</td>
<td>PageDown</td>
<td></td>
</tr>
<tr>
<td>end</td>
<td>35</td>
<td>End</td>
<td>End</td>
<td></td>
</tr>
<tr>
<td>home</td>
<td>36</td>
<td>Home</td>
<td>Home</td>
<td></td>
</tr>
<tr>
<td>left arrow</td>
<td>37</td>
<td>ArrowLeft</td>
<td>ArrowLeft</td>
<td></td>
</tr>
<tr>
<td>up arrow</td>
<td>38</td>
<td>ArrowUp</td>
<td>ArrowUp</td>
<td></td>
</tr>
<tr>
<td>right arrow</td>
<td>39</td>
<td>ArrowRight</td>
<td>ArrowRight</td>
<td></td>
</tr>
<tr>
<td>down arrow</td>
<td>40</td>
<td>ArrowDown</td>
<td>ArrowDown</td>
<td></td>
</tr>
<tr>
<td>print screen</td>
<td>44</td>
<td>PrintScreen</td>
<td>PrintScreen</td>
<td></td>
</tr>
<tr>
<td>insert</td>
<td>45</td>
<td>Insert</td>
<td>Insert</td>
<td></td>
</tr>
<tr>
<td>delete</td>
<td>46</td>
<td>Delete</td>
<td>Delete</td>
<td></td>
</tr>
<tr>
<td>0</td>
<td>48</td>
<td>0</td>
<td>Digit0</td>
<td></td>
</tr>
<tr>
<td>1</td>
<td>49</td>
<td>1</td>
<td>Digit1</td>
<td></td>
</tr>
<tr>
<td>2</td>
<td>50</td>
<td>2</td>
<td>Digit2</td>
<td></td>
</tr>
<tr>
<td>3</td>
<td>51</td>
<td>3</td>
<td>Digit3</td>
<td></td>
</tr>
<tr>
<td>4</td>
<td>52</td>
<td>4</td>
<td>Digit4</td>
<td></td>
</tr>
<tr>
<td>5</td>
<td>53</td>
<td>5</td>
<td>Digit5</td>
<td></td>
</tr>
<tr>
<td>6</td>
<td>54</td>
<td>6</td>
<td>Digit6</td>
<td></td>
</tr>
<tr>
<td>7</td>
<td>55</td>
<td>7</td>
<td>Digit7</td>
<td></td>
</tr>
<tr>
<td>8</td>
<td>56</td>
<td>8</td>
<td>Digit8</td>
<td></td>
</tr>
<tr>
<td>9</td>
<td>57</td>
<td>9</td>
<td>Digit9</td>
<td></td>
</tr>
<tr>
<td>a</td>
<td>65</td>
<td>a</td>
<td>KeyA</td>
<td></td>
</tr>
<tr>
<td>b</td>
<td>66</td>
<td>b</td>
<td>KeyB</td>
<td></td>
</tr>
<tr>
<td>c</td>
<td>67</td>
<td>c</td>
<td>KeyC</td>
<td></td>
</tr>
<tr>
<td>d</td>
<td>68</td>
<td>d</td>
<td>KeyD</td>
<td></td>
</tr>
<tr>
<td>e</td>
<td>69</td>
<td>e</td>
<td>KeyE</td>
<td></td>
</tr>
<tr>
<td>f</td>
<td>70</td>
<td>f</td>
<td>KeyF</td>
<td></td>
</tr>
<tr>
<td>g</td>
<td>71</td>
<td>g</td>
<td>KeyG</td>
<td></td>
</tr>
<tr>
<td>h</td>
<td>72</td>
<td>h</td>
<td>KeyH</td>
<td></td>
</tr>
<tr>
<td>i</td>
<td>73</td>
<td>i</td>
<td>KeyI</td>
<td></td>
</tr>
<tr>
<td>j</td>
<td>74</td>
<td>j</td>
<td>KeyJ</td>
<td></td>
</tr>
<tr>
<td>k</td>
<td>75</td>
<td>k</td>
<td>KeyK</td>
<td></td>
</tr>
<tr>
<td>l</td>
<td>76</td>
<td>l</td>
<td>KeyL</td>
<td></td>
</tr>
<tr>
<td>m</td>
<td>77</td>
<td>m</td>
<td>KeyM</td>
<td></td>
</tr>
<tr>
<td>n</td>
<td>78</td>
<td>n</td>
<td>KeyN</td>
<td></td>
</tr>
<tr>
<td>o</td>
<td>79</td>
<td>o</td>
<td>KeyO</td>
<td></td>
</tr>
<tr>
<td>p</td>
<td>80</td>
<td>p</td>
<td>KeyP</td>
<td></td>
</tr>
<tr>
<td>q</td>
<td>81</td>
<td>q</td>
<td>KeyQ</td>
<td></td>
</tr>
<tr>
<td>r</td>
<td>82</td>
<td>r</td>
<td>KeyR</td>
<td></td>
</tr>
<tr>
<td>s</td>
<td>83</td>
<td>s</td>
<td>KeyS</td>
<td></td>
</tr>
<tr>
<td>t</td>
<td>84</td>
<td>t</td>
<td>KeyT</td>
<td></td>
</tr>
<tr>
<td>u</td>
<td>85</td>
<td>u</td>
<td>KeyU</td>
<td></td>
</tr>
<tr>
<td>v</td>
<td>86</td>
<td>v</td>
<td>KeyV</td>
<td></td>
</tr>
<tr>
<td>w</td>
<td>87</td>
<td>w</td>
<td>KeyW</td>
<td></td>
</tr>
<tr>
<td>x</td>
<td>88</td>
<td>x</td>
<td>KeyX</td>
<td></td>
</tr>
<tr>
<td>y</td>
<td>89</td>
<td>y</td>
<td>KeyY</td>
<td></td>
</tr>
<tr>
<td>z</td>
<td>90</td>
<td>z</td>
<td>KeyZ</td>
<td></td>
</tr>
<tr>
<td>left window key</td>
<td>91</td>
<td>Meta</td>
<td>MetaLeft</td>
<td><code>event.metaKey</code> is true</td>
</tr>
<tr>
<td>right window key</td>
<td>92</td>
<td>Meta</td>
<td>MetaRight</td>
<td><code>event.metaKey</code> is true</td>
</tr>
<tr>
<td>select key (Context Menu)</td>
<td>93</td>
<td>ContextMenu</td>
<td>ContextMenu</td>
<td></td>
</tr>
<tr>
<td>numpad 0</td>
<td>96</td>
<td>0</td>
<td>Numpad0</td>
<td></td>
</tr>
<tr>
<td>numpad 1</td>
<td>97</td>
<td>1</td>
<td>Numpad1</td>
<td></td>
</tr>
<tr>
<td>numpad 2</td>
<td>98</td>
<td>2</td>
<td>Numpad2</td>
<td></td>
</tr>
<tr>
<td>numpad 3</td>
<td>99</td>
<td>3</td>
<td>Numpad3</td>
<td></td>
</tr>
<tr>
<td>numpad 4</td>
<td>100</td>
<td>4</td>
<td>Numpad4</td>
<td></td>
</tr>
<tr>
<td>numpad 5</td>
<td>101</td>
<td>5</td>
<td>Numpad5</td>
<td></td>
</tr>
<tr>
<td>numpad 6</td>
<td>102</td>
<td>6</td>
<td>Numpad6</td>
<td></td>
</tr>
<tr>
<td>numpad 7</td>
<td>103</td>
<td>7</td>
<td>Numpad7</td>
<td></td>
</tr>
<tr>
<td>numpad 8</td>
<td>104</td>
<td>8</td>
<td>Numpad8</td>
<td></td>
</tr>
<tr>
<td>numpad 9</td>
<td>105</td>
<td>9</td>
<td>Numpad9</td>
<td></td>
</tr>
<tr>
<td>multiply</td>
<td>106</td>
<td>*</td>
<td>NumpadMultiply</td>
<td></td>
</tr>
<tr>
<td>add</td>
<td>107</td>
<td>+</td>
<td>NumpadAdd</td>
<td></td>
</tr>
<tr>
<td>subtract</td>
<td>109</td>
<td>-</td>
<td>NumpadSubtract</td>
<td></td>
</tr>
<tr>
<td>decimal point</td>
<td>110</td>
<td>.</td>
<td>NumpadDecimal</td>
<td></td>
</tr>
<tr>
<td>divide</td>
<td>111</td>
<td>/</td>
<td>NumpadDivide</td>
<td></td>
</tr>
<tr>
<td>f1</td>
<td>112</td>
<td>F1</td>
<td>F1</td>
<td></td>
</tr>
<tr>
<td>f2</td>
<td>113</td>
<td>F2</td>
<td>F2</td>
<td></td>
</tr>
<tr>
<td>f3</td>
<td>114</td>
<td>F3</td>
<td>F3</td>
<td></td>
</tr>
<tr>
<td>f4</td>
<td>115</td>
<td>F4</td>
<td>F4</td>
<td></td>
</tr>
<tr>
<td>f5</td>
<td>116</td>
<td>F5</td>
<td>F5</td>
<td></td>
</tr>
<tr>
<td>f6</td>
<td>117</td>
<td>F6</td>
<td>F6</td>
<td></td>
</tr>
<tr>
<td>f7</td>
<td>118</td>
<td>F7</td>
<td>F7</td>
<td></td>
</tr>
<tr>
<td>f8</td>
<td>119</td>
<td>F8</td>
<td>F8</td>
<td></td>
</tr>
<tr>
<td>f9</td>
<td>120</td>
<td>F9</td>
<td>F9</td>
<td></td>
</tr>
<tr>
<td>f10</td>
<td>121</td>
<td>F10</td>
<td>F10</td>
<td></td>
</tr>
<tr>
<td>f11</td>
<td>122</td>
<td>F11</td>
<td>F11</td>
<td></td>
</tr>
<tr>
<td>f12</td>
<td>123</td>
<td>F12</td>
<td>F12</td>
<td></td>
</tr>
<tr>
<td>num lock</td>
<td>144</td>
<td>NumLock</td>
<td>NumLock</td>
<td></td>
</tr>
<tr>
<td>scroll lock</td>
<td>145</td>
<td>ScrollLock</td>
<td>ScrollLock</td>
<td></td>
</tr>
<tr>
<td>audio volume mute</td>
<td>173</td>
<td>AudioVolumeMute</td>
<td></td>
<td>⚠️ The <code>event.which</code> value is 181 in Firefox. Also FF provides the code value as, <code>VolumeMute</code></td>
</tr>
<tr>
<td>audio volume down</td>
<td>174</td>
<td>AudioVolumeDown</td>
<td></td>
<td>⚠️ The <code>event.which</code> value is 182 in Firefox. Also FF provides the code value as, <code>VolumeDown</code></td>
</tr>
<tr>
<td>audio volume up</td>
<td>175</td>
<td>AudioVolumeUp</td>
<td></td>
<td>⚠️ The <code>event.which</code> value is 183 in Firefox. Also FF provides the code value as, <code>VolumeUp</code></td>
</tr>
<tr>
<td>media player</td>
<td>181</td>
<td>LaunchMediaPlayer</td>
<td></td>
<td>⚠️ The ️<code>event.which</code> value is 0(no value) in Firefox. Also FF provides the code value as, <code>MediaSelect</code></td>
</tr>
<tr>
<td>launch application 1</td>
<td>182</td>
<td>LaunchApplication1</td>
<td></td>
<td>⚠️ The ️<code>event.which</code> value is 0(no value) in Firefox. Also FF provides the code value as, <code>LaunchApp1</code></td>
</tr>
<tr>
<td>launch application 2</td>
<td>183</td>
<td>LaunchApplication2</td>
<td></td>
<td>⚠️ The ️<code>event.which</code> value is 0(no value) in Firefox. Also FF provides the code value as, <code>LaunchApp2</code></td>
</tr>
<tr>
<td>semi-colon</td>
<td>186</td>
<td>;</td>
<td>Semicolon</td>
<td>⚠️ The <code>event.which</code> value is 59 in Firefox</td>
</tr>
<tr>
<td>equal sign</td>
<td>187</td>
<td>=</td>
<td>Equal</td>
<td>⚠️ The <code>event.which</code> value is 61 in Firefox</td>
</tr>
<tr>
<td>comma</td>
<td>188</td>
<td>,</td>
<td>Comma</td>
<td></td>
</tr>
<tr>
<td>dash</td>
<td>189</td>
<td>-</td>
<td>Minus</td>
<td>⚠️ The <code>event.which</code> value is 173 in Firefox</td>
</tr>
<tr>
<td>period</td>
<td>190</td>
<td>.</td>
<td>Period</td>
<td></td>
</tr>
<tr>
<td>forward slash</td>
<td>191</td>
<td>/</td>
<td>Slash</td>
<td></td>
</tr>
<tr>
<td>Backquote/Grave accent</td>
<td>192</td>
<td>`</td>
<td>Backquote</td>
<td></td>
</tr>
<tr>
<td>open bracket</td>
<td>219</td>
<td>[</td>
<td>BracketLeft</td>
<td></td>
</tr>
<tr>
<td>back slash</td>
<td>220</td>
<td>\</td>
<td>Backslash</td>
<td></td>
</tr>
<tr>
<td>close bracket</td>
<td>221</td>
<td>]</td>
<td>BracketRight</td>
<td></td>
</tr>
<tr>
<td>single quote</td>
<td>222</td>
<td>'</td>
<td>Quote</td>
<td></td>
</tr>
</tbody>
</table><!--kg-card-end: html--><p>Debes tener en cuenta:</p><!--kg-card-begin: markdown--><ul>
<li><code>event.which</code> ha quedado obsoleta</li>
<li>El valor de <code>event.code</code> es el mismo para letras minúsculas (a) y mayúsculas (A). El valor de <code>event.key</code> representa la letra real.</li>
<li>El valor de <code>event.which</code> es diferente en Firefox (FF) y otros navegadores para las teclas <code>igual(=)</code>, <code>punto y coma(;)</code> y <code>guión/menos(-)</code></li>
</ul>
<!--kg-card-end: markdown--><h2 id="en-resumen">En resumen</h2><p>Para resumir:</p><!--kg-card-begin: markdown--><ul>
<li>Puedes usar <code>KeyboardEvent</code> para capturar las interacciones del usuario usando el teclado.</li>
<li>Hay primariamente tres eventos de teclado <code>keydown</code>, <code>keypress</code> y <code>keyup</code>.</li>
<li>Deberíamos usar el evento <code>keydown</code> tanto como sea posible, ya que satisface la mayoría de los casos de uso.</li>
<li>La propiedad <code>event.which</code> ha quedado obsoleta. Usa <code>event.key</code> cuando sea posible.</li>
<li>Si tienes que dar soporte a navegadores antiguos, usa las alternativas apropiadas para la detección de teclas.</li>
<li>Podemos combinar múltiples teclas y realizar operaciones.</li>
<li>Los teclados virtuales soportan estos eventos siempre y cuando el layout y funciones sean similares al teclado estandar.</li>
</ul>
<!--kg-card-end: markdown--><p>Eso es todo por ahora. ¡Gracias por leer hasta aquí! Conectémonos. Puedes @ me en Twitter (@tapasadhikary) con comentarios o siéntete libre de seguirme.</p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Tutorial Excel VBA: Como escribir código en una hoja de cálculo usando Visual Basic ]]>
                </title>
                <description>
                    <![CDATA[ www.freecodecamp.org/espanol/news/tutorial-excel-vba-como-escribir-codigo-en-una-hoja-de-calculo-usando-visual-basic ]]>
                </description>
                <link>https://www.freecodecamp.org/espanol/news/tutorial-excel-vba/</link>
                <guid isPermaLink="false">62abea2229d2a808a7260284</guid>
                
                    <category>
                        <![CDATA[ VBA ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Mauricio Ignacio Fuentes Bravo ]]>
                </dc:creator>
                <pubDate>Sun, 03 Jul 2022 03:41:48 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/espanol/news/content/images/2022/07/excel-1771393_1920.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artículo original:</strong> <a href="https://www.freecodecamp.org/news/excel-vba-tutorial/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">Excel VBA Tutorial – How to Write Code in a Spreadsheet Using Visual Basic</a>
      </p><h2 id="introducci-n">Introducción</h2><p>Este es un tutorial sobre como escribir código en hojas de cálculos Excel usando Visual Basic para Aplicaciones (VBA).</p><p>Excel es uno de los productos más populares de Microsoft. En 2016, el CEO de Microsoft dijo "<em>Piensa en un mundo sin Excel. Eso es simplemente algo imposible para mí</em>". Bueno, tal vez el mundo no pueda pensar sin Excel.</p><!--kg-card-begin: markdown--><ul>
<li>En 1996, había sobre 30 millones de usuarios de Microsoft Excel (<a href="https://news.microsoft.com/1996/05/20/more-than-30-million-users-make-microsoft-excel-the-worlds-most-popular-spreadsheet-program/">fuente</a>).</li>
<li>Hoy en día, hay un estimado de 750 millones de usuarios de Microsoft Excel. Eso es un poco más que la población de Europa y 25 veces más usuarios que los que había en 1996.</li>
</ul>
<!--kg-card-end: markdown--><p>¡<a href="https://news.microsoft.com/1996/05/20/more-than-30-million-users-make-microsoft-excel-the-worlds-most-popular-spreadsheet-program/">S</a>omos una gran familia feliz!</p><p>En este tutorial aprenderás acerca de VBA y como escribir código en una hoja de cálculo Excel usando Visual Basic</p><h2 id="prerrequisitos">Prerrequisitos</h2><p>No necesitas experiencia previa programando para entender este tutorial. Sin embargo, necesitarás:</p><!--kg-card-begin: markdown--><ul>
<li>Familiaridad básica a intermedia con Microsoft Excel</li>
<li>Si quieres seguir los ejemplos de este artículo, necesitarás acceso a Microsoft Excel, preferentemente la última versión (2019) pero Excel 2016 y Excel 2013 funcionarán bien.</li>
<li>Voluntad para probar nuevas cosas.</li>
</ul>
<!--kg-card-end: markdown--><h2 id="objetivos-de-aprendizaje">Objetivos de aprendizaje</h2><p>a lo largo de este artículo aprenderás:</p><!--kg-card-begin: markdown--><ol>
<li>Qué es VBA</li>
<li>Porqué deberías usar VBA</li>
<li>Como configurar Excel para escribir VBA</li>
<li>Como resolver problemas reales con VBA</li>
</ol>
<!--kg-card-end: markdown--><h2 id="conceptos-importantes">Conceptos Importantes</h2><p>Aquí hay algunos conceptos importantes con los que deberías estar familiarizado para entender completamente este tutorial.</p><p><strong>Objetos</strong>: Excel es orientado a objetos, lo que significa que todo es un objeto - la ventana de excel, el libro de trabajo, una hoja, un gráfico, una celda. VBA permite a los usuarios manipular y realizar acciones con los objetos en Excel.</p><p>Si no tienes experiencia con programación orientada a objetos y es un concepto completamente nuevo, tomate un segundo para dejar que asiente.</p><p><strong>Procedimientos</strong>: un procedimiento es una porción de código VBA escrito en el editor Visual Basic que realiza una tarea, esto también se conoce como una macro (más sobre macros a continuación). Existen dos tipos de procedimientos: </p><!--kg-card-begin: markdown--><ul>
<li>Subrutinas: un grupo de declaraciones VBA que realizan una o más acciones.</li>
<li>Funciones: un grupo de declaraciones VBA que realizan una o más acciones y <em>retornan uno o más valores</em></li>
</ul>
<!--kg-card-end: markdown--><p>Nota: puedes tener funciones operando dentro de subrutinas. Lo verás más adelante.</p><p><strong>Macros</strong>: Si has pasado algún tiempo aprendiendo funcionalidades más avanzadas de Excel, probablemente encontraste el concepto de "macro". Los usuarios de Excel pueden grabar macros, consistentes en comandos/pulsiones de teclas/clics, que luego se vuelven a ejecutar a la velocidad de la luz para realizar tareas repetitivas. Las macros grabadas generan código VBA, el cual podrás examinar. De hecho, es divertido grabar una macro simple y luego mirar el código VBA.</p><p>Por favor ten en cuenta que algunas veces será más sencillo y rápido grabar una macro que escribir a mano un procedimiento VBA.</p><p>Por ejemplo, tal vez trabajas en administración de proyectos. Una vez a la semana, tendrás que convertir un reporte sin formato exportado de tu sistema de gestión de proyectos en un reporte limpio y bellamente formateado para liderazgo. Necesitarás formatear los nombres de proyectos que están sobre el presupuesto en texto "negrita" y color rojo. Podrías grabar los cambios de formato como una macro y luego ejecutarla cada vez que necesites realizar un cambio.</p><h2 id="-qu-es-vba">¿Qué es VBA?</h2><p>Visual Basic for Applications es un lenguaje de programación desarrollado por Microsoft. Cada programa de software en la suite Microsoft Office viene con el lenguaje VBA sin costo extra. VBA permite a los usuarios de Office crear pequeños programas que operan dentro del software Microsoft Office.</p><p>Piensa en VBA como un horno de pizza dentro de un restaurante. Excel es el restaurante. La cocina viene con electrodomésticos comerciales estandarizados, como refrigeradores grandes, estufas y viejos hornos regulares - estas son todas las características estándar de Excel.</p><p>Pero, ¿Qué pasa si quieres hacer pizza con leña? No podremos hacerlo en un horno comercial estándar. VBA es el horno de pizza.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/espanol/news/content/images/2022/06/image-2.png" class="kg-image" alt="image-2" srcset="https://www.freecodecamp.org/espanol/news/content/images/size/w600/2022/06/image-2.png 600w, https://www.freecodecamp.org/espanol/news/content/images/2022/06/image-2.png 1000w" sizes="(min-width: 720px) 720px" width="1000" height="603" loading="lazy"></figure><p>Ñam!.</p><h2 id="-por-qu-usar-vba-en-excel">¿Por qué usar VBA en Excel?</h2><p>¡Porque la pizza cocinada con leña es la mejor!</p><p>Pero en serio.</p><p>Mucha gente usa <em>mucho tiempo</em> en Excel como parte de sus trabajos. El tiempo en Excel se mueve diferente también. Dependiendo de las circunstancias, 10 minutos en Excel pueden parecer una eternidad si no eres capaz de hacer lo que necesitas, o 10 horas pueden pasar muy rápido si todo va muy rápido y bien. Es entonces cuando debes preguntarte, <strong>¿por qué diablos estoy pasando 10 horas en Excel?</strong></p><p>A veces, estos días son inevitables. Pero, si estás pasando 8-10 horas cada día en Excel haciendo tareas repetitivas, repitiendo mucho de los mismos procesos, tratando de limpiar después que otra persona use el archivo, o incluso actualizando otros archivos después de cambios realizados al archivo Excel, un procedimiento VBA podría ser la solución precisa para ti.</p><p>Deberías considerar usar VBA si necesitas:</p><!--kg-card-begin: markdown--><ul>
<li>Automatizar tareas repetitivas</li>
<li>Crear maneras fáciles para que los usuarios interactúen con tus hojas</li>
<li>Manipular grandes cantidades de datos</li>
</ul>
<!--kg-card-end: markdown--><h2 id="configurando-el-entorno-para-escribir-vba-en-excel">Configurando el entorno para escribir VBA en Excel</h2><h3 id="ficha-desarrollador">Ficha desarrollador</h3><p>Para escribir VBA, necesitas agregar la ficha Desarrollador a la Cinta de Opciones, así verás la Cinta de Opciones de la siguiente forma</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/espanol/news/content/images/2022/06/image-3.png" class="kg-image" alt="Cinta de opciones Excel" srcset="https://www.freecodecamp.org/espanol/news/content/images/size/w600/2022/06/image-3.png 600w, https://www.freecodecamp.org/espanol/news/content/images/size/w1000/2022/06/image-3.png 1000w, https://www.freecodecamp.org/espanol/news/content/images/size/w1600/2022/06/image-3.png 1600w, https://www.freecodecamp.org/espanol/news/content/images/2022/06/image-3.png 1920w" sizes="(min-width: 720px) 720px" width="1920" height="225" loading="lazy"></figure><p>Para agregar la ficha Desarrollador a la Cinta debes:</p><!--kg-card-begin: markdown--><ol>
<li>En la ficha archivo, ir a Opciones &gt; Personalizar Cinta de Opciones.</li>
<li>Bajo "Personalizar Cinta de Opciones" y bajo "Pestañas principales", selecciona el check box Desarrollador</li>
</ol>
<!--kg-card-end: markdown--><p>Después de mostrar la pestaña, la pestaña Desarrollador permanecerá visible, a menos que hallas limpiado la casilla de verificación o tengas que reinstalar Excel. <a href="https://support.microsoft.com/es-mx/topic/show-the-developer-tab-e1192344-5e56-4d45-931b-e5fd9bea2d45?ui=es-mx&amp;rs=es-mx&amp;ad=es">Para más información, mira la documentación de ayuda Microsoft</a></p><h2 id="editor-vba">Editor VBA</h2><p>Navega a la pestaña Desarrollador, y luego haz clic en el botón Visual Basic. Una nueva ventana aparecerá - este es el editor Visual Basic. Para los propósitos de este tutorial, solo debes estar familiarizado con el panel Explorador de Proyecto y el panel Propiedades del Proyecto</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/espanol/news/content/images/2022/06/image-4.png" class="kg-image" alt="image-4" srcset="https://www.freecodecamp.org/espanol/news/content/images/size/w600/2022/06/image-4.png 600w, https://www.freecodecamp.org/espanol/news/content/images/size/w1000/2022/06/image-4.png 1000w, https://www.freecodecamp.org/espanol/news/content/images/size/w1600/2022/06/image-4.png 1600w, https://www.freecodecamp.org/espanol/news/content/images/2022/06/image-4.png 2074w" sizes="(min-width: 720px) 720px" width="2074" height="2182" loading="lazy"></figure><h2 id="ejemplos-de-excel-vba">Ejemplos de Excel VBA</h2><p>Primero, creemos un archivo para jugar.</p><!--kg-card-begin: markdown--><ol>
<li>Abre un nuevo archivo de Excel</li>
<li>Grabalo como un libro habilitado para macros (maro-enabled workbook) (.xlsm)</li>
<li>Selecciona la ficha Desarrollador</li>
<li>Abre el editor VBA</li>
</ol>
<!--kg-card-end: markdown--><p>Vamos a rock and roll con algunos ejemplos sencillos para que escribas código en una hoja de cálculo usando Visual Basic.</p><p>Ejemplo #1: Mostrar un mensaje cuando los usuarios abran el libro de Excel.</p><p>En el editor VBA, elige insertar -&gt; Nuevo Módulo</p><p>Escribe este código en la ventana Módulo (no lo pegues!):</p><p>Sub Auto_open()<br>MsgBox("Bienvenido al libro de trabajo XYZ.")<br>End Sub</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/espanol/news/content/images/2022/06/image-5.png" class="kg-image" alt="image-5" width="281" height="200" loading="lazy"></figure><p>charaan! </p><h2 id="-c-mo-hace-esto">¿Cómo hace esto?</h2><p>Dependiendo de cuan familiarizado estés con la programación, tal vez intuyes algunas cosas. No es particularmente complejo, pero están pasando muchas cosas:</p><!--kg-card-begin: markdown--><ul>
<li>Sub (abreviación de "Subrutina"): recuerda de lo antes descrito, "un grupo de declaraciones VBA que realizan una o más acciones".</li>
<li>Auto_Open: esta es la subrutina específica. Esta ejecutará automáticamente tu cógigo cuando el archivo excel se abre - este es el evento que gatilla el procedimiento. Auto_Open sólo se ejecutará cuando el libro de trabajo se abre manualmente; y no se ejecutará si el libro de trabajo es abierto vía código desde otro libro de trabajo (Workbook_Open hará esto, <a href="https://www.pcreview.co.uk/threads/auto_open-vs-workbook_open.953960/">aprende más sobre las diferencias entre estos dos</a>)</li>
<li>Por defecto, el acceso a una subrutina es público. Esto significa que cualquier otro módulo puede usar esta subrutina. Todos los ejemplos de este tutorial serán subrutinas públicas. Si lo necesitas, puedes declarar subrutinas de forma privada. Esto puede ser necesario en algunas ocasiones. <a href="https://www.thespreadsheetguru.com/blog/2014/3/5/explaining-private-vs-public-declarations">Aprende más sobre modificadores de acceso a subrutinas</a></li>
<li>MsgBox: esta es una función - un grupo de declaraciones que realiza una o más acciones y retorna un valor. El valor retornado es el mensaje "Bienvenido al libro de trabajo XYZ"</li>
</ul>
<!--kg-card-end: markdown--><p>En resumen, esta es una subrutina simple que contiene una función</p><h2 id="-cu-ndo-podr-a-usar-esto">¿Cuándo podría usar esto?</h2><p>Tal vez tienes un archivo muy importante, el cual tiene acceso de manera poco frecuente (digamos, una vez cada cuatrimestre), pero que es actualizado automáticamente por otro procedimiento VBA. Cuando se accede a este, es por muchas personas, en múltiples departamentos, alrededor de toda la compañía.</p><!--kg-card-begin: markdown--><ul>
<li>Problema: La mayoría del tiempo cuando los usuarios acceden al archivo, ellos están confundidos respecto al propósito de este archivo (porqué existe), como es actualizado tan frecuentemente, quien lo mantiene, y cómo deberían interactuar con él. Los recién contratados siempre tienen un montón de preguntas, y tu tienes que contestar estas preguntas una y otra vez.</li>
<li>Solución: Crear un mensaje a los usuarios que contenga respuestas específicas a cada una de estas preguntas frecuentes.</li>
</ul>
<!--kg-card-end: markdown--><h2 id="ejemplos-del-mundo-real">Ejemplos del Mundo Real</h2><!--kg-card-begin: markdown--><ul>
<li>Usar la función MsgBox para mostrar un mensaje cuando haya algún evento: el usuario cierra el libro de trabajo, el usuario imprime, una nueva hoja es agregada al libro de trabajo, etc.</li>
<li>Usar la función MsgBox para mostar un mensaje cuando el usuario necesite llenar una condición antes de cerrar el libro de trabajo Excel</li>
<li>Usar la función InputBox para obtener información del usuario</li>
</ul>
<!--kg-card-end: markdown--><h2 id="ejemplo-2-permitir-al-usuario-ejecutar-otro-procedimiento">Ejemplo #2: Permitir al usuario ejecutar otro procedimiento</h2><p>En el editor VBA selecciona Insertar -&gt; Nuevo Módulo</p><p>Escribe este código en la ventana Módulo (no lo pegues!):</p><p></p><!--kg-card-begin: markdown--><blockquote>
<p>Sub UserReportQuery()<br>
Dim UserInput As Long<br>
Dim Answer As Integer<br>
UserInput = vbYesNo<br>
Answer = MsgBox("¿Desea procesar el reporte XYZ?",UserInput)<br>
if Answer = vbYes Then ProcessReport<br>
End Sub</p>
</blockquote>
<blockquote>
<p>Sub ProcessReport()<br>
MsgBox("Gracias por procesar el reporte XYZ")<br>
End Sub</p>
</blockquote>
<!--kg-card-end: markdown--><p>Grábalo y navega de vuelta a la pestaña navegadora de Excel y selecciona la opción "Botón". Haz clic en una celda y asigna la macro UserReportQuery al botón.</p><p>Ahora haz clic en el botón. Este mensaje debería aparecer</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/espanol/news/content/images/2022/06/image-7.png" class="kg-image" alt="image-7" width="362" height="273" loading="lazy"></figure><p>Si haces clic en "Sí" o aprietas Enter.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/espanol/news/content/images/2022/06/image-8.png" class="kg-image" alt="image-8" width="409" height="304" loading="lazy"></figure><p>¡¡Otra vez, tada!!</p><p>Pon atención a la subrutina secundaria "ProcessReport", podría ser <em>cualquier cosa. </em>Lo demostraré con más posibilidades en el ejemplo #3. Pero primero...</p><h2 id="-c-mo-est-haciendo-esto">¿Cómo está haciendo esto?</h2><p>Este ejemplo está construido sobre el ejemplo anterior con algunos elementos nuevos. Revisemos las cosas nuevas:</p><!--kg-card-begin: markdown--><ul>
<li>Dim UserInput As Long: Dim es un diminutivo de "dimensión" y te permite declarar nombres de variables. En este caso, UserInput es el nombre de variable y Long es el tipo de dato. En español esta línea significa "Aquí hay una variable llamada "UserInput", y es de tipo Largo".</li>
<li>Dim Answer as Integer: declara otra variable llamada "Answer", con el tipo de dato entero (integer). <a href="https://docs.microsoft.com/es-mx/dotnet/visual-basic/language-reference/data-types/">Aprende más sobre el tipo de datos aquí</a></li>
<li>UserInput = vbYesNo: asigna un valor a la variable. En este caso, vbYesNo, el cual muestra los botones Sí y No. Hay muchos tipos de botones, <a href="https://docs.microsoft.com/es-mx/office/vba/language/reference/user-interface-help/msgbox-function">aprende más sobre ellos aquí</a></li>
<li>Answer = MsgBox("¿Desea procesar el reporte XYZ?", UserInput): asigna a la variable Answer la función MsgBox y la variable UserInput. Si, una variable dentro de una variable.</li>
<li>If Answer = vbYes Then ProcessReport: esto es una "declaración if" una declaración condicional, la cual te permite decir si x es verdad, entonces hacer y. En este caso, si el usuario ha seleccionado "Sí", entonces ejecutar la subrutina ProcessReport.</li>
</ul>
<!--kg-card-end: markdown--><h2 id="-cu-ndo-puedo-usar-esto">¿Cuándo puedo usar esto?</h2><p>Esto se puede usar de muchas, muchas maneras. El valor y versatilidad de esta funcionalidad está más definido por lo que hace la subrutina secundaria.</p><p>Por ejemplo, tal vez tienes un archivo que es usado para generar tres reportes semanales. Estos reportes están formateados de manera muy distinta.</p><!--kg-card-begin: markdown--><ul>
<li>Problema: Cada vez que es necesario generar un reporte, un usuario abre el archivo y cambia los formatos y lo gráficos, así con cada usuario. Este archivo está siendo editado exhaustivamente a lo menos 3 veces a la semana, y toma a lo menos 30 minutos cada vez que es editado.</li>
<li>Solución: Crear un botón por tipo de reporte, el cual automáticamente reformatea los componentes necesarios de los reportes y genera los gráficos necesarios.</li>
</ul>
<!--kg-card-end: markdown--><h2 id="ejemplos-del-mundo-real-1">Ejemplos del Mundo Real</h2><!--kg-card-begin: markdown--><ul>
<li>Crear un cuadro de dialogo para que un usuario pueda poblar una información determinada a través de múltiples hojas.</li>
<li>Usar la función InputBox para obtener información del usuario, la cual luego será utilizada para poblar múltiples hojas</li>
</ul>
<!--kg-card-end: markdown--><h2 id="ejemplo-3-agregar-n-meros-a-un-rango-con-un-ciclo-for-next">Ejemplo #3: Agregar números a un rango con un ciclo For-Next</h2><p>Los ciclos for son muy útiles si necesitas realizar tareas repetitivas en un rango específico de valores, arreglos o rangos de celdas. En español, un ciclo dice "para cada x, haz y" ("for each x, doy" - en inglés)</p><p>En el editor VBA, seleccione Insertar -&gt; Nuevo Módulo</p><p>Escribe el siguiente código en la ventana módulo (no lo pegues!!):</p><!--kg-card-begin: markdown--><blockquote>
<p>Sub LoopExample()<br>
Dim X As Integer<br>
For X = 1 to 100<br>
Range("A"&amp;X).Value = X<br>
Next X<br>
End Sub</p>
</blockquote>
<!--kg-card-end: markdown--><p>Guarda y luego navega de vuelta a la pestaña desarrollador de Excel, agrega un botón macro. Corre la macro LoopExample.</p><p>Esto debería pasar:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/espanol/news/content/images/2022/06/image-9.png" class="kg-image" alt="image-9" width="176" height="690" loading="lazy"></figure><p>Hasta llegar a la fila 100-ésima.</p><h2 id="-c-mo-hace-esto-1">¿Cómo hace esto?</h2><!--kg-card-begin: markdown--><ul>
<li>Dim X As Integer: declara la variable X como un dato de tipo entero</li>
<li>For X=1 To 100: este es el comienzo del ciclo For. En palabras simples, le dice al ciclo repite esto hasta que X = 100. X es el contador. El ciclo se seguirá ejecutando hasta X = 100, ejecuta una última vez y luego se detiene.</li>
<li>Range("A"&amp;X).Value = X: esto declara el rango del ciclo y qué poner en ese rango. Desde X = 1 inicialmente, la primera celda será A1, en cuyo lugar el ciclo pondrá X en esa celda.</li>
<li>Next X: le dice al ciclo que se ejecute otra vez.</li>
</ul>
<!--kg-card-end: markdown--><h2 id="-cu-ndo-puedo-usar-esto-1">¿Cuándo puedo usar esto?</h2><p>El ciclo For-Next es una de las funcionalidades más poderosas de VBA; existen muchos casos de uso potenciales. Este e un ejemplo más complejo que requerirá múltiples capas de lógica, pero comunica un mundo de posibilidades en los ciclos For-Next.</p><p>Tal vez tienes una lista de todos los productos vendidos en tu pastelería en la Columna A, el tipo de producto en la Columna B (queques, donas o muffins), el costo de los ingredientes en la Columna C, y el precio promedio de mercado de cada tipo de producto en otra hoja.</p><p>Necesitas saber cuál debería ser el precio de venta de cada producto. Piensas que debería ser el costo de los ingredientes más un 20%, pero también 1.2% bajo el precio promedio de mercado en caso de ser posible. Un ciclo For-Next podrían permitirte hacer este tipo de cálculos.</p><h2 id="ejemplos-del-mundo-real-2">Ejemplos del Mundo Real</h2><!--kg-card-begin: markdown--><ul>
<li>Usa un ciclo con una declaración if anidada para agregar valores específicos a un arreglo separado sólo si se cumplen ciertas condiciones</li>
<li>Realizar cálculos matematicos en cada valor de un rango, i.e. calcular cargos adicionales y agregarlos al valor</li>
<li>iterar sobre cada caracter en un texto (string) y extraer todos los números</li>
<li>Elegir aleatoriamente números de valores en un array</li>
</ul>
<!--kg-card-end: markdown--><h2 id="conclusi-n">Conclusión</h2><p>Ahora que hemos hablado acerca de pizza y mufins y claro, como escribir código VBA en hojas de Excel, hagamos un chequeo del aprendizaje. Revisa si puedes responder estas preguntas.</p><!--kg-card-begin: markdown--><ul>
<li>¿Qué es VBA?</li>
<li>¿Como configurar el enterno para comenzar a usar VBA en Excel?</li>
<li>¿Como y cuando debes usar VBA?</li>
<li>¿Cuales son algunos problemas que puedes resolver con VBA?</li>
</ul>
<!--kg-card-end: markdown--><p>Si tienes una idea clara de cómo responder estas preguntas, entonces esto fue un éxito.</p><p>Ya sea que eres un usuario ocasional o un usuario avanzado, espero que este tutorial provea información útil acerca de lo que podemos conseguir con un poco de código en tus hojas de Excel.</p><p>¡Feliz código! </p><h2 id="recursos-de-aprendizaje">Recursos de aprendizaje</h2><!--kg-card-begin: markdown--><ul>
<li>Excel VBA Programming for Dummies, John Walkenbach</li>
<li><a href="https://docs.microsoft.com/es-mx/office/vba/library-reference/concepts/getting-started-with-vba-in-office">Introducción a VBA en Office</a></li>
<li><a href="https://www.linkedin.com/learning/learning-vba-in-excel-2019/dive-into-using-vba-in-excel?autoplay=true">Learning VBA in Excel, Lynda</a></li>
</ul>
<!--kg-card-end: markdown--><h2 id="un-poco-de-la-autora-original">Un poco de la autora original</h2><p>Chloe Tucker, artísta y desarrolladora en Portland, Oregon. Como educadora, estoy continuamente buscando la intersección entre aprender y enseñar, o entre tecnología y arte. Me puedes encontrar en Twitter <a href="https://twitter.com/_chloetucker">@_chloetucker</a> y revisar mi sitio web <a href="https://chloe.dev/">chloe.dev</a></p> ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
