<?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[ JavaScript - 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[ JavaScript - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/espanol/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Tue, 05 May 2026 19:48:28 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/espanol/news/tag/javascript/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ Delegación de eventos en JavaScript: explicado con un ejemplo ]]>
                </title>
                <description>
                    <![CDATA[ Delegación de eventos es un patrón basado en el concepto de Propagación de eventos (Event Bubbling). Es un patrón de manejo de eventos que permite gestionar eventos en un nivel superior del árbol del DOM, en lugar de hacerlo directamente en el nivel donde el evento fue inicialmente recibido. Hay ]]>
                </description>
                <link>https://www.freecodecamp.org/espanol/news/delegacion-de-eventos-en-javascript-explicado-con-un-ejemplo/</link>
                <guid isPermaLink="false">677d94c1f310b3064b9abc82</guid>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Diego Velesaca Orellana ]]>
                </dc:creator>
                <pubDate>Wed, 05 Feb 2025 15:53:42 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/espanol/news/content/images/2025/02/2.-event-delegation-js.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artículo original:</strong> <a href="https://www.freecodecamp.org/news/event-delegation-javascript/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">Event Delegation in JavaScript –Explained with an Example</a>
      </p><p>Delegación de eventos es un patrón basado en el concepto de <strong>Propagación de eventos (Event Bubbling)</strong>. Es un patrón de manejo de eventos que permite gestionar eventos en un nivel superior del árbol del DOM, en lugar de hacerlo directamente en el nivel donde el evento fue inicialmente recibido.</p><p>Hay una <a href="https://www.freecodecamp.org/espanol/news/evento-bubbling-en-javascript-como-funciona-la-propagacion-de-eventos-con-ejemplos/">versión en video de este tema</a><strong> </strong>si tú lo prefieres<strong>.</strong></p><h2 id="una-breve-introducci-n-a-propagaci-n-de-eventos-">Una breve introducción a propagación de eventos.</h2><p>Por defecto, los eventos desencadenados en un elemento se propagan hacia arriba en el árbol del DOM hasta el elemento padre, sus ancestros, y finalmente hasta el elemento raíz (<code>html</code>).</p><p>Mira este ejemplo.</p><pre><code class="language-html">&lt;div&gt;
  &lt;span&gt;
    &lt;button&gt;Click Me!&lt;/button&gt;
  &lt;/span&gt;
&lt;/div&gt;</code></pre><p>Aquí tenemos un, <code>div</code> el cual es padre de un, <code>span</code> quien a su vez es padre del elemento <code>button</code>.</p><p>Debido a la propagación de eventos, cuando el botón recibe un evento, por ejemplo un clic, el evento se propaga hacia arriba en el árbol del DOM, &nbsp;por lo que el <code>span</code> y el <code>div</code> también recibirán el evento respectivamente.</p><p>Si quieres aprender acerca de propagación de eventos más a detalle, puedes &nbsp;<a href="https://www.freecodecamp.org/espanol/news/evento-bubbling-en-javascript-como-funciona-la-propagacion-de-eventos-con-ejemplos/">leer un artículo sobre esto aquí</a><strong> .</strong></p><h2 id="-c-mo-funciona-la-delegaci-n-de-eventos">¿Cómo funciona la delegación de eventos?</h2><p>Con la delegación de eventos, en lugar de manejar el evento en el <code>button</code> puedes manejarlo en el <code>div</code>.</p><p>La idea es "<strong>delegar</strong>" el manejo de un evento a un elemento diferente (en este caso, el div, que es el elemento padre) en lugar del elemento actual (el botón) que recibió el evento.</p><p>Aquí tienes un ejemplo en código de lo que quiero decir:</p><pre><code class="language-js">const div = document.getElementsByTagName("div")[0]

div.addEventListener("click", (event) =&gt; {
  if(event.target.tagName === 'BUTTON') {
    console.log("button was clicked")
  }
})</code></pre><p>El objeto <code>event</code> tiene una propiedad <code>target</code> que contiene información &nbsp;sobre el elemento que realmente recibió el evento. Con <code>target.element</code> &nbsp;obtenemos el nombre de la etiqueta del elemento y verificar si es<strong> BUTTON.</strong></p><p>Con este código, cuando haces clic en el <code>button</code> , el evento se propaga hacia arriba hasta el <code>div</code> el cual maneja el evento.</p><h2 id="beneficios-de-la-delegaci-n-de-eventos-">Beneficios de la delegación de eventos.</h2><p>La delegación de eventos es un patrón útil que te permite escribir código más limpio y reducir la cantidad de <strong>event listeners (escuchadores de eventos)</strong>, especialmente cuando comparten una lógica similar.</p><p>¿A qué me refiero con esto? Mira este código:</p><pre><code class="language-html">&lt;div&gt;
  &lt;button&gt;Button 1&lt;/button&gt;
  &lt;button&gt;Button 2&lt;/button&gt;
  &lt;button&gt;Button 3&lt;/button&gt;
&lt;/div&gt;</code></pre><p>Aquí tenemos 3 botones. Supongamos que queremos manejar un evento clic en cada botón, de manera que, al hacer clic, el texto del botón se registre en la consola. Podemos implementarlo de la siguiente manera:</p><pre><code class="language-js">const buttons = document.querySelectorAll('button')

buttons.forEach(button =&gt; {
  button.addEventListener("click", (event) =&gt; {
    console.log(event.target.innerText)
  })
})</code></pre><p>Usamos <code>querySelectorAll</code> aquí porque devuelve &nbsp;un <code>NodeList</code>, el cual permite usar el método <code>forEach</code>. Por otro lado, &nbsp;<code>getElementByTagName</code> devuelve una, <code>HTMLCollection</code> el cual no tiene el método <code>forEach</code>, por lo que no se podría iterar de la misma manera.</p><p>Cuando haces clic en el primer botón, se registra "Button 1" en la consola. Para el segundo botón, se registra "Button 2", &nbsp;y para el tercer botón, se registra "Button 3".</p><p>Aunque esto funciona como esperamos, hemos definido &nbsp;tres event listeners, uno para cada botón.</p><p>Dado que el evento clic en estos botones se propaga hacia arriba en el árbol del DOM, podemos usar un elemento padre ó ancestro común para manejar el evento. En este caso, delegamos la lógica a un elemento ancestro compartido, encargándose de gestionar el evento para todos los botones.</p><p>A continuación, te explicamos cómo:</p><pre><code class="language-js">const div = document.querySelector('div')

div.addEventListener("click", (event) =&gt; {
  if(event.target.tagName === 'BUTTON') {
    console.log(event.target.innerText)
  }
})</code></pre><p>Ahora, tenemos solo un event listener, pero la misma lógica: cuando haces clic en el primer botón, "Button 1" se registra en la consola, y lo mismo ocurre para los demás botones. </p><p>Incluso si agregamos un botón adicional como este: </p><pre><code class="language-html">&lt;div&gt;
  &lt;button&gt;Button 1&lt;/button&gt;
  &lt;button&gt;Button 2&lt;/button&gt;
  &lt;button&gt;Button 3&lt;/button&gt;
  &lt;button&gt;Button 4&lt;/button&gt;
&lt;/div&gt;</code></pre><p>No tendremos que modificar el código JavaScript porque el nuevo botón &nbsp;también comparte el <code>div</code> padre (el cual delegamos para manjera los eventos) con los otros botones.</p><h2 id="conclusi-n">Conclusión</h2><p>Con la delegación de eventos, reduces la cantidad de event listeners y centralizas la lógica basada en eventos en solo lugar. Esto facilita agregar y remover elementos sin necesidad de agregar o remover manualmente event listeners existentes.</p><p>Delegación de eventos es posible, gracias la propagación de eventos en el DOM, donde el evento que recibe un elemento hijo también se transmite a su elemento, padre y ancestros. Nuevamente, puedes <a href="https://www.freecodecamp.org/espanol/news/evento-bubbling-en-javascript-como-funciona-la-propagacion-de-eventos-con-ejemplos/">leer más acerca de propagación de evento aquí</a>.</p><p>¡Gracias por leer, y happy coding!</p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Tutorial de React: Cómo trabajar con múltiples casillas de verificación ]]>
                </title>
                <description>
                    <![CDATA[ Trabajar con múltiples casillas en React es completamente diferente a cómo se usan las casillas de verificación en HTML. Por lo que en este artículo, vamos a ver cómo hacerlo en React. Aprenderás a:  * Cómo usar una casilla de verificación como Input Controlado en React,  * Cómo ]]>
                </description>
                <link>https://www.freecodecamp.org/espanol/news/a-continuacion-vamos-a-establecer-que-el-valor-totalprice-al-estado-total-utilizando-settotal-totalprice/</link>
                <guid isPermaLink="false">6743c47f6ab3ae04514079c9</guid>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Constanza Areal ]]>
                </dc:creator>
                <pubDate>Fri, 24 Jan 2025 16:19:29 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/espanol/news/content/images/2025/01/checkbox_selection.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Trabajar con múltiples casillas en React es completamente diferente a cómo se usan las casillas de verificación en HTML.</p><p>Por lo que en este artículo, vamos a ver cómo hacerlo en React.</p><p>Aprenderás a:</p><ul><li>Cómo usar una casilla de verificación como Input Controlado en React,</li><li>Cómo usar los métodos de arreglo "map" y "reduce" para cálculos complejos,</li><li>Cómo crear un arreglo de un largo específico y con valores pre cargados,</li></ul><p> y mucho más.</p><p>Este artículo es parte de mi curso <em><a href="https://master-redux.yogeshchavan.dev/">Mastering Redux</a>.</em> Aquí tienes un <a href="https://www.youtube.com/watch?v=izSw74H08Bc">adelanto de la aplicación</a> que vamos a crear en el curso.</p><p>Así que empecemos.</p><h2 id="c-mo-trabajar-con-una-sola-casilla-de-verificaci-n"><strong>Cómo trabajar con una sola casilla de verificación</strong></h2><p>Antes de aprender a trabajar con varias casillas, empezaremos programando solo uno.</p><p>En este artículo, para crear componentes voy a estar usando la sintaxis de React Hooks. Si no estás familiarizado con esta sintaxis, puedes darle un vistazo a mi artículo [en inglés] <a href="https://levelup.gitconnected.com/an-introduction-to-react-hooks-50281fd961fe?source=friends_link&amp;sk=89baff89ec8bc637e7c13b7554904e54"><em>Introduction to React Hooks</em></a><em>.</em></p><p>Mira el siguiente código:</p><pre><code class="language-js">&lt;div className="App"&gt;
  Select your pizza topping:
  &lt;div className="topping"&gt;
    &lt;input type="checkbox" id="topping" name="topping" value="Paneer" /&gt;Paneer
  &lt;/div&gt;
&lt;/div&gt;
</code></pre><p> Aquí tienes la <a href="https://codesandbox.io/s/young-snow-lzplh?file=/src/App.js">demo</a>.</p><p>En el código de arriba, declaramos una única casilla.</p><p>Como se muestra abajo, podemos seleccionar y de seleccionarlo de manera muy fácil: </p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2021/05/check_uncheck-1.gif" class="kg-image" alt="Image" width="600" height="400" loading="lazy"></figure><p>Pero para mostrar en pantalla si está seleccionado o no, tenemos que convertirlo a un Input Controlado.</p><p>En React, los Inputs Controlados se manejan mediante el estado, por lo que solamente podemos cambiar el &nbsp;valor del input cambiando su estado.</p><p>Mira el siguiente código:</p><pre><code class="language-js">export default function App() {
  const [isChecked, setIsChecked] = useState(false);

  const handleOnChange = () =&gt; {
    setIsChecked(!isChecked);
  };

  return (
    &lt;div className="App"&gt;
      Select your pizza topping:
      &lt;div className="topping"&gt;
        &lt;input
          type="checkbox"
          id="topping"
          name="topping"
          value="Paneer"
          checked={isChecked}
          onChange={handleOnChange}
        /&gt;
        Paneer
      &lt;/div&gt;
      &lt;div className="result"&gt;
        Above checkbox is {isChecked ? "checked" : "un-checked"}.
      &lt;/div&gt;
    &lt;/div&gt;
  );
}
</code></pre><p>y aquí tienes la <a href="https://codesandbox.io/s/dazzling-oskar-qcil8?file=/src/App.js">demo</a></p><p>En el código de arriba, con el hook <code>useState</code> &nbsp;declaramos el estado <code>isChecked</code> del componente, con el valor inicial <code>false</code>: </p><pre><code class="language-js">const [isChecked, setIsChecked] = useState(false);
</code></pre><p>Después, a la casilla de verificación le damos dos <em>props</em> adicionales, <code>checked</code> y <code>onChange</code>, de la siguiente manera:</p><pre><code class="language-js">&lt;input
  ...
  checked={isChecked}
  onChange={handleOnChange}
/&gt;
</code></pre><p>Cuando hagamos clic en la casilla de verificación, la función <code>handleOnChange</code> será la encargada de cambiar el valor del estado <code>isChecked</code></p><pre><code class="language-js">const handleOnChange = () =&gt; {
  setIsChecked(!isChecked);
};
</code></pre><p>Entonces, si la casilla está seleccionado, el valor de <code>isChecked</code> es <code>false</code>. Pero si no lo está, el valor es<code>true</code> al usar <code>!isChecked</code>.</p><p>De esta manea la casilla se convierte en un input controlado, cuyo valor es manejado mediante el estado del componente.</p><p>Hay que tener en cuenta que en React siempre se recomienda usar inputs controlados para los campos de inputs, aun si el código luce complicado. Esto garantiza que el cambio del input solo ocurra dentro de la función <code>onChange</code>.</p><p>El estado de un input no podrá ser cambiado de otra forma y así siempre tendrás el valor correcto y actual del estado del input.</p><p>Solo en raras ocasiones se puede usar React ref para poder manejar el input de manera no controlada.</p><h2 id="c-mo-manipular-m-ltiples-casillas-de-verificaci-n"><strong>Cómo manipular múltiples casillas de verificación</strong></h2><p>Veamos ahora como trabajar con varias casillas.</p><p>Mira esta <a href="https://codesandbox.io/s/mystifying-tu-xlpgb?file=/src/App.js">demo</a></p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2021/05/multiple_checkboxes-2.png" class="kg-image" alt="Image" width="600" height="400" loading="lazy"></figure><p> Aquí estamos mostrando una lista de aderezos y sus precios. Dependiendo cuantos aderezos sean seleccionados, necesitamos mostrar el monto total.</p><p>Antes, cuando teníamos un solo casilla de verificación, solo teníamos el estado <code>isChecked</code> para cambiar el estado de la casilla de verificación.</p><p>Pero ahora, como tenemos varias casillas de verificación, no es práctico hacer varios llamados <code>useState</code> para cada uno.</p><p>Entonces, declaremos un arreglo dentro del estado e indiquemos el estado de cada una de las casillas de verificación.</p><p>Para crear un arreglo cuyo largo sea igual número de casillas de verificación, Podemos usar el método de arreglo <code>fill</code> de este método:</p><pre><code class="language-js">const [checkedState, setCheckedState] = useState(
    new Array(toppings.length).fill(false)
);
</code></pre><p>Aquí hemos declarado un estado con un valor inicial como un arreglo relleno con el valor <code>false</code>.</p><p>Entonces, si témenos cinco coberturas, el arreglo de estado <code>checkedState</code> tendrá cinco valores <code>false</code>:</p><pre><code class="language-js">[false, false, false, false, false]
</code></pre><p>Y una vez que marquemos / desmarquemos la casilla, cambiaremos el <code>false</code> correspondiente a <code>true</code> y viceversa.</p><p>Aquí está la demo <a href="https://www.freecodecamp.org/espanol/news/ghost/#/editor/post/6743c47f6ab3ae04514079c9:~:text=https%3A/codesandbox.io/s/wild%2Dsilence%2Db8k2j%3Ffile%3D/src/App.js">final</a>.</p><p>Y el código completo de <code>App.js</code> luce de esta manera:</p><pre><code class="language-js">import { useState } from "react";
import { toppings } from "./utils/toppings";
import "./styles.css";

const getFormattedPrice = (price) =&gt; `$${price.toFixed(2)}`;

export default function App() {
  const [checkedState, setCheckedState] = useState(
    new Array(toppings.length).fill(false)
  );

  const [total, setTotal] = useState(0);

  const handleOnChange = (position) =&gt; {
    const updatedCheckedState = checkedState.map((item, index) =&gt;
      index === position ? !item : item
    );

    setCheckedState(updatedCheckedState);

    const totalPrice = updatedCheckedState.reduce(
      (sum, currentState, index) =&gt; {
        if (currentState === true) {
          return sum + toppings[index].price;
        }
        return sum;
      },
      0
    );

    setTotal(totalPrice);
  };

  return (
    &lt;div className="App"&gt;
      &lt;h3&gt;Select Toppings&lt;/h3&gt;
      &lt;ul className="toppings-list"&gt;
        {toppings.map(({ name, price }, index) =&gt; {
          return (
            &lt;li key={index}&gt;
              &lt;div className="toppings-list-item"&gt;
                &lt;div className="left-section"&gt;
                  &lt;input
                    type="checkbox"
                    id={`custom-checkbox-${index}`}
                    name={name}
                    value={name}
                    checked={checkedState[index]}
                    onChange={() =&gt; handleOnChange(index)}
                  /&gt;
                  &lt;label htmlFor={`custom-checkbox-${index}`}&gt;{name}&lt;/label&gt;
                &lt;/div&gt;
                &lt;div className="right-section"&gt;{getFormattedPrice(price)}&lt;/div&gt;
              &lt;/div&gt;
            &lt;/li&gt;
          );
        })}
        &lt;li&gt;
          &lt;div className="toppings-list-item"&gt;
            &lt;div className="left-section"&gt;Total:&lt;/div&gt;
            &lt;div className="right-section"&gt;{getFormattedPrice(total)}&lt;/div&gt;
          &lt;/div&gt;
        &lt;/li&gt;
      &lt;/ul&gt;
    &lt;/div&gt;
  );
}
</code></pre><p>Veamos que estamos haciendo aquí.</p><p>Como se muestra aquí abajo, hemos declarado la casilla de verificación de entrada como se muestra a continuación:</p><pre><code class="language-js">&lt;input
  type="checkbox"
  id={`custom-checkbox-${index}`}
  name={name}
  value={name}
  checked={checkedState[index]}
  onChange={() =&gt; handleOnChange(index)}
/&gt;
</code></pre><p>Aquí, agregamos el atributo <code>checked</code> con el valor del estado <code>checkedState</code>, <code>true</code> o <code>false</code>, según corresponda.</p><p>También añadimos un manejador <code>onChange</code> y le pasamos el <code>index</code> de la casilla que está marcada/desmarcada al método &nbsp;<code>handleOnChange</code>.</p><p>El método manejador <code>handleOnChange</code> debe verse así:</p><pre><code class="language-js">const handleOnChange = (position) =&gt; {
  const updatedCheckedState = checkedState.map((item, index) =&gt;
    index === position ? !item : item
  );

  setCheckedState(updatedCheckedState);

  const totalPrice = updatedCheckedState.reduce(
    (sum, currentState, index) =&gt; {
      if (currentState === true) {
        return sum + toppings[index].price;
      }
      return sum;
    },
    0
  );

  setTotal(totalPrice);
};
</code></pre><p>Aquí, primero recorremos el array <code>checkedState</code> utilizando el método arreglo <code>map</code>. Si el valor del parámetro <code>position</code> pasado coincide con el <code>index</code> actual, entonces invertimos su valor. Entonces, si el valor es <code>true</code> se convertirá en <code>false</code> usando <code>!item</code> y si el valor es <code>false</code>, entonces se convertirá en <code>true</code></p><p>Si el <code>index</code> no coincide con el parámetro <code>position</code> proporcionado, entonces no estamos invirtiendo su valor, sino que simplemente devolvemos el valor tal cual.</p><pre><code class="language-js">const updatedCheckedState = checkedState.map((item, index) =&gt;
  index === position ? !item : item
);

// the above code is the same as the below code

const updatedCheckedState = checkedState.map((item, index) =&gt; {
  if (index === position) {
    return !item;
  } else {
    return item;
  }
});
</code></pre><p>He utilizado el operador ternario <code>?:</code> porque hace el código más corto, pero puedes utilizar cualquier método de arreglo.</p><p>Si no estás familiarizado como &nbsp;funcionan los métodos <code>map</code> o<code>reduce</code>, puedes echarle un vistazo a este artículo que <a href="https://www.freecodecamp.org/news/complete-introduction-to-the-most-useful-javascript-array-methods/">escribí</a>.</p><p>Luego, establecemos el arreglo <code>checkedState</code> en el &nbsp;arreglo <code>updatedCheckedState</code>. Esto es importante porque si no actualizamos el estado <code>checkedState</code> dentro del manejador &nbsp;<code>handleOnChange</code>, entonces no podrás marcar/desmarcar la casilla de verificación.</p><p>Esto es porque estamos usando el valor de <code>checkedState</code> de la casilla para determinar si este está o no marcada (ya que es una entrada controlada como se muestra abajo):</p><pre><code class="language-js">&lt;input
  type="checkbox"
  ...
  checked={checkedState[index]}
  onChange={() =&gt; handleOnChange(index)}
/&gt;
</code></pre><p>Ten en cuenta que creamos una variable <code>updatedCheckedState</code> separada, y a su vez, esta se la pasamos a la función <code>updatedCheckedState</code> y no al arreglo original <code>checkedState</code>.</p><p>Esto es porque, por default, la función <code>setCheckedState</code> &nbsp;usada para actualizar el estado es asincrónica.</p><p>Llamar a la función <code>setCheckedState</code> no garantiza que obtendrás el valor actualizado del arreglo <code>checkedState</code> en la siguiente línea.</p><p>Por lo que creamos una variable separada y usamos esa en el método <code>reduce</code>.<br></p><p>Entonces, para calcular el precio total, usamos el método de arreglo &nbsp;<code>reduce</code>:</p><pre><code class="language-js">const totalPrice = updatedCheckedState.reduce(
  (sum, currentState, index) =&gt; {
    if (currentState === true) {
      return sum + toppings[index].price;
    }
    return sum;
  },
  0
);
</code></pre><p>El método de arreglo &nbsp;<code>reduce</code> recibe cuatro parámetros, de los cuales usaremos solamente tres: <code>sum</code>, <code>currentState</code> e <code>index</code>. Puedes usar nombres distintos, ya que son solo parámetros.</p><p>También estamos pasando el valor <code>0</code> como valor inicial, que también se lo conoce como el valor <code>accumulator</code> del parámetro <code>sum</code>.</p><p>Luego, dentro de la función reduce, chequeamos si el valor actual del array <code>checkedState</code> es <code>true</code> o no. </p><p>Si lo es <code>true</code>, esto significa que la casilla está marcada, por lo que añadiremos el valor correspondiente de <code>price</code> correspondiente utilizando <code>sum + toppings[index].price</code></p><p>Si el valor del arreglo <code>checkedState</code> es <code>false</code>, entonces no estamos añadiendo su precio, sino que solo estamos devolviendo el valor anterior calculado de <code>sum</code>.</p><p>Luego, vamos a establecer que el valor <code>totalPrice</code> al estado <code>total</code> utilizando <code>setTotal(totalPrice)</code></p><p>De esta forma, podemos calcular correctamente el precio total de los aderezos seleccionados como pueden ver debajo:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2021/05/toppings-1.gif" class="kg-image" alt="Image" width="600" height="400" loading="lazy"></figure><p>Aquí tiene el <a href="https://b8k2j.csb.app/">link</a> de la demo de arriba, así pueden probarla ustedes mismos.</p><h3 id="-gracias-por-leer-"><strong>¡Gracias por leer!</strong></h3><p>A muchos desarrolladores se les dificulta entender como funciona Redux, pero todo desarrollador especializado en React debe saber como trabajar con Redux, ya que muchos proyectos dentro de la industria usa Redux para gestionar proyectos de gran escala.</p><p>Para hacerlo fácil para ti, he creado el curso <em><a href="https://master-redux.yogeshchavan.dev/">Mastering Redux</a></em>.</p><p>En este curso, aprenderás Redux desde cero y también crearás un aplicación de pedido de comida, desde el inicio y con Redux.</p><p>Dale clic a la imagen de abajo para unirte al curso y obtener un descuento especial por tiempo limitado, además de también obtener mi libro más popular "<em>Mastering Modern JavaScript</em>", gratis.</p><figure class="kg-card kg-image-card"><img src="https://gist.github.com/myogeshchavan97/98ae4f4ead57fde8d47fcf7641220b72/raw/c3e4265df4396d639a7938a83bffd570130483b1/banner.jpg" class="kg-image" alt="banner" width="600" height="400" loading="lazy"></figure><p><strong>Si quieres mantenerte actualizado con contenidos sobre JavaScript, React y Node.js, <a href="https://www.linkedin.com/in/yogesh-chavan97/">sigueme en LinkedIn</a>.</strong></p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Cómo filtrar un arreglo en JavaScript – Filtrado de Arreglos y Objetos en JavaScript ]]>
                </title>
                <description>
                    <![CDATA[ Cuando estamos creando un programa dinámico e interactivo, puede ser que necesitemos agregar interacción. Por ejemplo, cuando un usuario hace clic en un botón para filtrar una lista larga de elementos. También puede ser que necesitemos manipular una gran cantidad de información para poder mostrar solo aquellos elementos que coinciden ]]>
                </description>
                <link>https://www.freecodecamp.org/espanol/news/untitled-4/</link>
                <guid isPermaLink="false">67324db3296a1703fde9bce2</guid>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Constanza Areal ]]>
                </dc:creator>
                <pubDate>Fri, 22 Nov 2024 07:00:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/espanol/news/content/images/2024/11/cover-template--2-.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Cuando estamos creando un programa dinámico e interactivo, puede ser que necesitemos agregar interacción. Por ejemplo, cuando un usuario hace clic en un botón para filtrar una lista larga de elementos.<br><br>También puede ser que necesitemos manipular una gran cantidad de información para poder mostrar solo aquellos elementos que coinciden con lo especificado por el usuario.<br><br>En este artículo, aprenderás a filtrar un <em>arreglo</em> en JavaScript de dos formas distintas. También aprenderás a filtrar un <em>arreglo </em>de objetos y devolver un arreglo compuesto por los elementos filtrados.</p><h2 id="c-mo-filtrar-un-arreglo-con-un-bucle-for">Cómo filtrar un arreglo con un <code>bucle for</code></h2><p>Antes del lanzamiento de ES6 en 2015, muchos desarrolladores dependían del método del <code>bucle for</code> para hacer todas las manipulaciones de <em>arreglos</em>. Pero como el código se volvía demasiado largo y difícil de entender, esto condujo a la creación de muchos métodos individuales de JavaScript como el método <code>filter()</code> (sobre el cual aprenderás más adelante).</p><p>Pero para empezar, y entender todo el panorama, vamos a aprender cómo hacerlo usando bucles.</p><p>Supongamos que tenemos un <em>arreglos </em>de objetos que contiene todos los datos de los usuarios como nombre, edad, ocupación, etc. y quieres filtrar aquellos usuarios cuya edad cumplan una determinada condición.</p><pre><code class="language-js">let users = [
    { name: 'John', age: 25, occupation: 'gardener' },
    { name: 'Lenny', age: 51, occupation: 'programmer' },
    { name: 'Andrew', age: 43, occupation: 'teacher' },
    { name: 'Peter', age: 81, occupation: 'teacher' },
    { name: 'Anna', age: 47, occupation: 'programmer' },
    { name: 'Albert', age: 76, occupation: 'programmer' },
]
</code></pre><p>También puedes querer filtrar el <em>arreglo </em>de objetos usando la edad para devolver un nuevo <em>arreglo </em>con aquellos usuarios cuya edad es mayor a 40 y cuya ocupación es igual a <code>programmer</code>:</p><pre><code class="language-js">let filteredUsers = [];
for (let i= 0; i&lt;users.length; i++) {
    if (users[i].age &gt; 40 &amp;&amp; users[i].occupation === 'programmer' ) {
        filteredUsers = [...filteredUsers, users[i]];
    }
}
console.log(filteredUsers);
</code></pre><p>Este código va a devolver un <em>arreglo </em>de tres usuarios que cumplen con esa condición:</p><figure class="kg-card kg-image-card"><img src="https://paper-attachments.dropboxusercontent.com/s_A2A56A7C05733A13745945CF4C6950EBC758CD93042A33CBFFD44710AB9E7883_1676527392206_image.png" class="kg-image" alt="s_A2A56A7C05733A13745945CF4C6950EBC758CD93042A33CBFFD44710AB9E7883_1676527392206_image" width="1562" height="244" loading="lazy"></figure><p>Si bien esto funciona bastante bien, una mejor manera de filtrar un <em>arreglo</em> es usando el método <code>filter()</code> de ES6.</p><h2 id="c-mo-filtrar-un-arreglo-con-el-m-todo-filter-filter-">Cómo filtrar un arreglo con el método filter<strong><strong> <code>filter()</code> </strong></strong></h2><p>El método <code>filter()</code> es un método ES6 con un sintaxis más prolija para filtrar un <em>arreglo.</em> Este método devuelve un nuevo arreglo con nuevos elementos, sin modificar el <em>arreglo </em>original.</p><pre><code class="language-js">// Sintaxis
myArray.filter(callbackFn)
</code></pre><p>En la función <em>callback</em>, hay que acceder a cada elemento, el índice y hasta el <em>arreglo </em>original:</p><pre><code class="language-js">myArray.filter((element, index, array) =&gt; { /* ... */ })
</code></pre><p>Ahora hagamos el mismo ejemplo, pero filtrando al usuario por su edad y ocupación:</p><pre><code class="language-js">let filteredUsers = users.filter((user) =&gt; {
    return user.age &gt; 40 &amp;&amp; user.occupation === 'programmer';
});

console.log(filteredUsers);
</code></pre><p>Esto devolverá el mismo resultado, pero seguro notarás que tu código queda más prolijo. También es importante que sepas que puedes reescribir este código en una sola línea, sin el <code>return</code>: </p><pre><code class="language-js">let filteredUsers = users.filter(user =&gt; user.age &gt; 40 &amp;&amp; user.occupation === 'programmer');
console.log(filteredUsers);
</code></pre><p>Ambos ejemplos de código van a retornar los usuarios filtrados:</p><figure class="kg-card kg-image-card"><img src="https://paper-attachments.dropboxusercontent.com/s_A2A56A7C05733A13745945CF4C6950EBC758CD93042A33CBFFD44710AB9E7883_1676527392206_image.png" class="kg-image" alt="s_A2A56A7C05733A13745945CF4C6950EBC758CD93042A33CBFFD44710AB9E7883_1676527392206_image" width="1562" height="244" loading="lazy"></figure><p>El método <code>filter()</code> hace que sea más fácil ejecutar más operaciones directas, sin crear demasiadas variables porque se encadena a otros métodos.</p><p>Por ejemplo, puedes filtrar el nuevo <em>arreglo</em> y devolver otro arreglo que contenga solo los nombres:</p><pre><code class="language-js">let filteredUserNames = users.filter(user =&gt; user.age &gt; 40 &amp;&amp; user.occupation === 'programmer')
    .sort((a, b) =&gt; a.age - b.age)
    .map(user =&gt; user.name);

console.log(filteredUserNames); // ['Anna', 'Lenny', 'Albert']
</code></pre><p>Para aprender más sobre cómo filtrar <em>arreglos</em> en JavaScript con el método <code>filter()</code>, puedes leer este artículo <a href="https://www.freecodecamp.org/espanol/news/tutorial-de-arrayfilter-de-javascript-como-iterar-a-traves-de-los-elementos-en-un-arreglo/">Tutorial de Array.filter() de JavaScript</a><a href="https://www.freecodecamp.org/news/javascript-array-filter-tutorial-how-to-iterate-through-elements-in-an-array/"> </a>y aprender <a href="https://www.freecodecamp.org/espanol/news/find-vs-filter-en-javascript-las-diferencias-a-traves-de-ejemplos/">aquí</a> sobre la diferencia entre los métodos <code>find()</code> y <code>filter()</code> de JavaScript.</p><h2 id="c-mo-filtrar-un-objeto-en-javascript">Cómo filtrar un objeto en JavaScript</h2><p>Los objetos de JavaScript no son iterables como los <em>arreglos</em> o las cadenas de texto. Esto significa que no pueden ser recorridos con un bucle <code>for</code>, el método <code>filter()</code> o cualquier otro método parecido a estos. Entonces ¿cómo se puede filtrar un objeto en JavaScript?</p><p>Esto se puede hacer convirtiendo el objeto en un <em>arreglo</em> mediante cualquier método de objeto como <code>Object.keys()</code>, <code>Object.values()</code> o <code>Object.entries()</code>. Luego, puedes usar el método <code>filter()</code> para filtrar a través del <em>arreglo </em>y devolver uno nuevo con los elementos filtrados.</p><p>Por ejemplo, si tenemos un objeto con datos de los usuarios como nombre, edad y ocupación. Estos métodos estáticos de objeto van a devolver las claves, valores o cada par clave-valor como un <em>arreglo</em>:</p><pre><code class="language-js">const userDetails = {
    firstName: "Jane",
    lastName: "Daniels",
    userName: "jane.daniels",
    email: "jane.daniels@example.com",
    comapny: "Example Inc.",
    address: "1234 Example Street",
    age : 25,
    hobby: "Singing"
};

let keysArray = Object.keys(userDetails);

console.log(keysArray);
</code></pre><p>Esto va a devolver un <em>arreglo</em> de las claves del objeto:</p><pre><code class="language-js">['firstName', 'lastName', 'userName', 'email', 'comapny', 'address', 'age', 'hobby']
</code></pre><p>Entonces, ahora, puedes usar el método <code>filter()</code> para recorrer el <em>arreglo </em>y devolver uno nuevo con los elementos filtrados:</p><pre><code class="language-js">let filteredKeys = keysArray.filter(key =&gt; key.length &gt; 5);

console.log(filteredKeys);
</code></pre><p>Esto va a devolver un<em> arreglo</em> con las claves que tengan un largo mayor a 5:</p><pre><code class="language-js">['firstName', 'lastName', 'userName', 'comapny', 'address', 'hobby']
</code></pre><p>Pero como seguro querrás utilizar un mejor método de filtrado, puedes, por ejemplo, filtrar el par clave-valor de nuestro objeto que incluya un nombre de un objeto mayor. Luego puedes obtener primeros las claves, filtrarlas y luego usar el método <code>reduce()</code> para reducir las claves filtradas a un objeto compuesto por estas claves y sus valores:</p><pre><code class="language-js">const userDetails = {
    firstName: "Jane",
    lastName: "Daniels",
    userName: "jane.daniels",
    email: "jane.daniels@example.com",
    comapny: "Example Inc.",
    address: "1234 Example Street",
    age : 25,
    hobby: "Singing"
};

const userNames = Object.keys(userDetails)
    .filter((key) =&gt; key.includes("Name"))
    .reduce((object, key) =&gt; {
        return Object.assign(object, {
          [key]: userDetails[key]
        });
  }, {});

console.log(userNames);
</code></pre><p>Esto devolverá un objeto con las claves filtradas y sus valores:</p><pre><code class="language-js">{
    firstName: "Jane",
    lastName: "Daniels",
    userName: "jane.daniels"
}
</code></pre><h2 id="conclusi-n">Conclusión</h2><p>En este artículo has aprendido a como filtrar un <em>arreglo </em>en JavaScript usando el bucle <code>for</code> y el método <code>filter()</code>, que tiene una mejor sintaxis para poder filtrar <em>arreglos</em> en JavaScript.</p><p>También has aprendido a filtrar un objeto en JavaScript, convirtiéndolo en un arreglo y luego usando el método <code>filter()</code>.</p><p>¡Gracias por leer y diviértete programando!</p><p>Puedes acceder a más de 188 de mis artículos visitando mi <a href="https://joelolawanle.com/contents">sitio web</a>. También puedes usar la barra de búsqueda para buscar si he escrito un artículo específico.</p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Señales en Angular - Cómo escribir código reactivo ]]>
                </title>
                <description>
                    <![CDATA[ ¡Una nueva y emocionante característica llega a Angular! Las señales, estas proveen una nueva forma de comunicación de nuestro código que comunique a nuestras plantillas que los datos han cambiado. Esto mejora la capacidad de detección de cambios de Angular, lo que también mejora el rendimiento y hace nuestro código ]]>
                </description>
                <link>https://www.freecodecamp.org/espanol/news/senales-en-angular-como-escribir-codigo-reactivo/</link>
                <guid isPermaLink="false">667384c4b6f94103d5aef8e9</guid>
                
                    <category>
                        <![CDATA[ angular ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Israel Palma ]]>
                </dc:creator>
                <pubDate>Fri, 08 Nov 2024 02:51:46 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/espanol/news/content/images/2024/06/thumbnail.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artículo original:</strong> <a href="https://www.freecodecamp.org/news/angular-signals/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">Signals in Angular – How to Write More Reactive Code</a>
      </p><p>¡Una nueva y emocionante característica llega a Angular! Las señales, estas proveen una nueva forma de comunicación de nuestro código que comunique a nuestras plantillas que los datos han cambiado. Esto mejora la capacidad de detección de cambios de Angular, lo que también mejora el rendimiento y hace nuestro código más reactivo.</p><p>Ya puedes probar las señales, están disponibles con acceso anticipado para desarrolladores (developer preview) en Angular v16, que se publicará en mayo de 2023. Te muestro como hacerlo más adelante.</p><p>Si gustas puedes ver el vídeo asociado (en inglés):</p><figure class="kg-card kg-embed-card" data-test-label="fitted">
        <div class="fluid-width-video-container">
          <div style="padding-top: 56.17977528089888%;" class="fluid-width-video-wrapper">
            <iframe width="356" height="200" src="https://www.youtube.com/embed/oqYQG7QMdzw?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen="" title="Angular Signals: What? Why? and How?" name="fitvid0" style="box-sizing: inherit; margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 22px; vertical-align: middle; position: absolute; top: 0px; left: 0px; width: 720px; height: 404.489px;"></iframe>
          </div>
        </div>
      </figure><p>Encuentra el código de este tutorial aquí: <a href="https://stackblitz.com/edit/angular-signals-deborahk">https://stackblitz.com/edit/angular-signals-deborahk</a>.</p><p>Antes de adentrarnos en detalles del "qué" y el "cómo", vamos a empezar con el "por qué". Entonces, ¿por qué usar las señales?</p><h2 id="-por-qu-necesitamos-las-se-ales"><strong>¿Por qué necesitamos las señales?</strong></h2><p>Empecemos con un ejemplo simple que no utiliza señales. Digamos que estás escribiendo código para realizar algunas operaciones matemáticas.</p><pre><code class="language-typescript">let x = 5;
let y = 3;
let z = x + y;
console.log(z);//~8</code></pre><p>¿Qué es lo que este código imprime por consola? Así es, imprime <code>8</code>.</p><p>En alguna parte más adelante en el código cambiamos el valor de <code>x</code>. ¿Qué valor de <code>z</code> se imprime por consola ahora?</p><pre><code class="language-typescript">let x = 5;
let y = 3;
let z = x + y;
console.log(z);

x = 10;
console.log(z);//~8</code></pre><p>¡Aún imprime <code>8</code>! Esto se debe a que el valor se asigna a <code>z</code> desde el inicio cuando la expresión se ha evaluado. La variable <code>z</code> no reacciona a los cambios en <code>x</code> o en <code>y</code>.</p><p>¡Pero queremos que nuestras variables reaccionen a los cambios! </p><p>Una de las razones por las que usamos Angular es para crear sitios web interactivos y reactivos, es decir, con capacidad de reaccionar a los cambios de los datos. </p><p>Como por ejemplo en la Figura 1. Cuando el usuario edita la cantidad, las variables relacionadas, como el total, sub-total e impuestos, deberían reaccionar y ajustar los costos automáticamente. Si el usuario decide borrar un item del carrito también queremos que las variables relacionadas sean capaces de re-calcular los costos.</p><figure class="kg-card kg-image-card kg-width-wide kg-card-hascaption"><img src="https://www.freecodecamp.org/espanol/news/content/images/2024/07/Cantidad.jpg" class="kg-image" alt="b3SbnD_bufoicCX2VGyQiA624LQEC7yIEAVeEj0aVHjxvwmNnTPs-qE565koSuPWUrjAj-UDSw9otj6fXRWHPtr9jce2fnLt8FFAiLP0KRijjpuUiN_cb9lFwe_IbmsSWSzWqV36zBa8Bsnh7ciX4zo" srcset="https://www.freecodecamp.org/espanol/news/content/images/2024/07/Cantidad.jpg 600w" width="600" height="253" loading="lazy"><figcaption>Figura 1. El carrito reacciona y re-calcula los precios cuando el usuario modifica la cantidad.</figcaption></figure><p>Con las señales nuestro código puede ser más reactivo. En nuestro anterior ejemplo la implementación de señales se vería así:</p><pre><code class="language-typescript">const x = signal(5);
const y = signal(3);
const z = computed(() =&gt; x() + y());
console.log(z()); // 8

x.set(10);
console.log(z()); // 13</code></pre><p>Veremos la sintaxis y lo demostraremos a detalle más adelante. Por ahora, el código de arriba define dos señales: <code>x</code> y <code>y</code> además de darles valores iniciales de <code>5</code> y <code>3</code>. Entonces definimos una señal computada <code>z</code>, que es la suma de <code>x</code> y <code>y</code>. Debido a que las señales proveen notificaciones de cambios cuando cambian los valores de las señales <code>x</code> o <code>y</code>, cualquier valor computado a partir de esas señales se re-calculará automáticamente. ¡Este código es reactivo! ¡Excelente!</p><p>Las señales computadas reaccionan y se re-calculan cuando cualquiera de sus señales dependientes cambia. Si una señal está vinculada en una plantilla de Angular, al cambiar dicha señal, el mecanismo de detección de cambios de Angular actualiza cualquier vista que pueda leer la señal. Y los usuarios visualizan los valores modificados.</p><p>Por lo que es posible dar respuesta a la pregunta de, ¿por qué necesitamos las señales? De la siguiente manera:</p><ul><li>Las señales permiten la reactividad.</li><li>Usando señales podemos tener mayor control en la detección de cambios, lo cual puede mejorar el desempeño.</li></ul><p>Profundicemos un poco más para entender lo que es una señal y cómo se usa.</p><h2 id="-qu-es-una-se-al"><strong>¿Qué es una señal?</strong></h2><p>Podemos pensar de una señal como un valor que además tiene la capacidad de notificar cambios. Una señal es un tipo especial de variable que almacena un valor. Pero a diferencia de otras variables, una señal también provee notificaciones cuando el valor de la variable cambia.</p><p>Imagínate una variable normal como si fuera un estante o repisa, como en el lado izquierdo de la figura 2. Cuando un valor se asigna a la variable, ésta se colocaría en el estante. Cualquier código dentro del alcance puede simplemente ver (leer) la variable en el estante.</p><figure class="kg-card kg-image-card kg-width-wide kg-card-hascaption"><img src="https://lh6.googleusercontent.com/VNW2DY2fkiBRNox5DIGkh2qr_yRgurq7I3vLumHSqT2ACNKq6I3GiGcMpVvU6f2AImTNIJ3quMh7lzerxfRjD3WBiLPEKBWGRgxGfvsrWpwuvBpvbpllPKJ-lZWHzQLRBguqAHWnITJU3xajiV2BoZM" class="kg-image" alt="VNW2DY2fkiBRNox5DIGkh2qr_yRgurq7I3vLumHSqT2ACNKq6I3GiGcMpVvU6f2AImTNIJ3quMh7lzerxfRjD3WBiLPEKBWGRgxGfvsrWpwuvBpvbpllPKJ-lZWHzQLRBguqAHWnITJU3xajiV2BoZM" width="1600" height="766" loading="lazy"><figcaption>Figura 2. Metafóricamente, una variable normal está en un estante. Una señal se almacena en una caja que brilla cuando cambia.</figcaption></figure><p>Una señal tiene mayor parecido a una caja, como se muestra al lado derecho de la figura 2. Al crear una señal, creamos algo análogo a una caja y el valor se coloca dentro de ésta. Cuando el valor que se encuentra dentro cambia, la caja emite un brillo para avisarle. Para leer la señal, es decir el valor almacenado, primero debemos abrir "la caja" usando paréntesis: <code>x()</code>. Técnicamente llamamos a la función "getter" (literal de conseguidor, método o función que devuelve un valor) de la señal para leer el valor de esta.</p><p>Ahora pues, ya sabemos que es una señal.</p><ul><li>Una señal es una variable con notificaciones de cambios.</li><li>Es un valor reactivo o bien un "reactivo primitivo".</li><li>Siempre tiene un valor</li><li>Es síncrona.</li><li>No es un sustituto o remplazo de RxJS ni de Observables para operaciones asíncronas como <code>http.get</code>.</li></ul><p>¿Dónde podemos usarlas?</p><ul><li>En <strong>componentes</strong> para monitorear su estado local. </li><li>En <strong>directivas</strong>.</li><li>En <strong>servicios </strong>para compartir el estado entre componentes.</li><li>Para su lectura en una <strong>plantilla</strong> (del inglés template) para mostrar lo valores.</li><li>O en cualquier otra parte de tu código.</li></ul><p>A continuación, vayamos paso a paso viendo cómo crear y usar señales.</p><h2 id="c-mo-crear-una-se-al"><strong>Cómo crear una señal</strong></h2><p>Para usar una señal tenemos primero, por supuesto, que crearla. </p><pre><code class="language-typescript">cantidad = signal&lt;number&gt;(1);</code></pre><p>Esta es la sintaxis para escribir el código para crear e inicializar una señal usando el método constructor <code>signal()</code>. </p><p>De forma opcional como podemos ver, es posible pasar un parámetro genérico para definir el tipo de dato de la señal. Una señal puede ser de tipo string, number, array, object o cualquier tipo de dato. En muchos casos el tipo de dato puede inferirse y por lo tanto no es necesario u obligatorio pasar el parámetro de tipo genérico. </p><p>Pasemos al constructor el valor por defecto para nuestra señal, ya que una señal siempre debe tener un valor, y por lo tanto, es necesario inicializarlas con un valor por defecto.</p><p>Aquí te muestro algunos otros ejemplos:</p><pre><code class="language-typescript">cantidad = signal(1);

cantidadDisponible = signal([1, 2, 3, 4, 5, 6]);

vehiculoSeleccionado = signal&lt;Vehiculo&gt;({ 
  id: 1,
  nombre: 'AT-AT', 
  precio: 19416.13
});

vehiculos = signal&lt;Vehiculo[]&gt;([]);</code></pre><p>La primera línea de este código crea una señal numérica con un valor por defecto (predefinido) de <code>1</code>. Ya que el valor predeterminado es de tipo <code>number</code>, la <code>cantidad</code> es una señal que contiene un número. El parámetro del tipo genérico no se necesita pasar, ya que como vimos el tipo del dato es inferido automáticamente.</p><p>La segunda línea es una señal que contiene un arreglo de números, donde su valor predefinido corresponde con los valores del 1 al 6. De nuevo, no necesitamos pasar el parámetro de tipo genérico ya que el tipo de dato se infiere automáticamente a partir del tipo de dato del valor que hemos pasado.</p><p>La señal <code>vehiculoSeleccionado</code> contiene un objeto de tipo <code>Vehiculo</code>. En este ejemplo el tipo no puede inferirse, por lo que especificamos un parámetro de tipo genérico para <code>Vehiculo</code>. </p><p>La señal <code>vehiculos</code> contiene un arreglo para objetos de tipo <code>Vehiculo</code>, que está vacío por defecto. Para que este arreglo posea tipos estático y pueda recibir elementos del tipo de dato <code>Vehiculo</code>, agregamos el parámetro genérico de tipo de datos <code>&lt;Vehiculo[]&gt;</code>. &nbsp; </p><p>Una señal que fue creada utilizando el constructor es editable, por lo que puedes asignarle un valor nuevo o diferente, actualizarla en base a su valor actual o mutar su contenido. En breve veremos ejemplos de cómo realizar estas operaciones.</p><p>Una vez que hayas creado una señal es posible que quieras leer su valor.</p><h2 id="c-mo-leer-una-se-al"><strong>Cómo leer una señal</strong></h2><p>Anteriormente planteamos pensar que una señal es una caja. Hablando metafóricamente podemos decir que para leer el valor de una señal es necesario primero abrir la caja. Ya que las señales son funciones, esto lo hacemos invocando la señal con el uso de paréntesis.</p><pre><code class="language-typescript">quantity();</code></pre><p>Empecemos con el nombre de la señal y enseguida con el paréntesis de apertura y luego el de cierre. Técnicamente esto a su vez invoca a la función "getter", la cual es creada "por debajo", por lo que no es visible en el código.</p><p>Cuando se trabaja con Angular es común leer las señales en el "template" (plantilla).</p><pre><code class="language-html">&lt;select
    [ngModel]="cantidad()"
    (change)="alSeleccionarCantidad($any($event.target).value)"&gt;
  &lt;option *ngFor="let c of cantidadDisponible()"&gt;{{ c }}&lt;/option&gt;
&lt;/select&gt;

&lt;div&gt;Vehículo: {{ vehiculoSeleccionado().nombre }}&lt;/div&gt;
&lt;div&gt;Price: {{ vehiculoSeleccionado().precio }}&lt;/div&gt;
&lt;div [style.color]="color()"&gt;Total: {{ precioTotal() }}&lt;/div&gt;</code></pre><p>La plantilla de arriba muestra una caja de selección de cantidad. La directiva <code>[ngModel]</code> lee el valor de la señal <code>cantidad</code> y crea un enlace o "binding" a ese valor.</p><p>El enlace o "binding" al evento <code>change</code> invoca el método <code>alSeleccionarCantidad()</code> del componente.</p><p>El elemento html <code>option</code> usa la directiva <code>ngFor</code> para iterar por cada elemento del arreglo en la señal <code>cantidadDisponible</code>. Lee la señal y crea una opción en el <code>select</code> para cada elemento del arreglo.</p><p>Debajo del elemento <code>select</code> encontrarás tres elementos <code>div</code>, el primero lee la señal <code>vehiculoSeleccionado</code>, luego accede a su propiedad <code>nombre</code>. El segundo elemento <code>div</code> lee la señal <code>vehiculoSeleccionado</code> y muestra su propiedad <code>precio</code>. El último <code>div</code> lee la señal <code>precioTotal</code> (que no hemos definido aún), y utiliza el valor de la señal <code>color</code> (que tampoco hemos definido todavía) para determinar el color del texto.</p><p>Es importante nota que al leer una señal siempre obtendremos el valor actual, y el código no tiene conocimiento de ningún valor previo.</p><p>Cuando el usuario elige una cantidad diferente en el elemento <code>select</code> queremos cambiar el valor de la señal <code>cantidad</code>. De esa manera la señal <code>cantidad</code> se transforma en la "fuente de verdad" para la cantidad seleccionada por el usuario. Veamos cómo hacerlo a continuación.</p><h2 id="c-mo-cambiar-el-valor-de-una-se-al"><strong>Cómo cambiar el valor de una señal</strong></h2><p>El método <code>set</code> reemplaza el valor de una señal con un nuevo valor. Básicamente "abre la caja", quita el ítem actual y asigna un nuevo ítem que tomará el lugar del anterior.</p><pre><code class="language-typescript">this.cantidad.set(cant);</code></pre><p>Una situación común es cambiar el valor de la señal en base a una acción del usuario. Por ejemplo:</p><ul><li>El usuario selecciona una nueva cantidad usando el elemento <code>select</code>.</li><li>El evento ligado al elemento <code>select</code> invoca al método <code>alSeleccionarCantidad()</code> y pasa la cantidad seleccionada por el usuario.</li><li>La acción del usuario se maneja en el componente usando la función o método definido para este propósito. </li><li>El nuevo valor se asigna a la señal <code>cantidad</code>.</li></ul><p>Este es un ejemplo de una función para el manejo de eventos (event handler):</p><pre><code class="language-typescript">alSeleccionarCantidad(cant: number) {
  this.cantidad.set(cant);
}</code></pre><p>En el momento en que se haya asignado o re-asignado la señal, el código notifica a cualquier consumidor de la señal que esta ha cambiado. En este contexto, un consumidor es cualquier código que tenga interés en recibir notificaciones de cambios del valor de la señal. </p><p>¿Cómo es que el consumidor indica que tiene interés en ser notificado de los cambios de una señal en particular?</p><p>Si <strong>un código lee una señal</strong>, ese código será notificado cuando la señal cambie.</p><p>Si <strong>una plantilla lee una señal</strong>, será notificada cuando la señal cambie y la "vista" (view) sea programada para volver a renderizarse.</p><p>Por lo que el acto de leer una señal registra el interés del consumidor de observar el valor y los cambios de dicha señal. El equipo de Angular le llama a esto la <strong>regla de oro</strong> de las señales en componentes: "la detección de cambios en un componente se agendará cuando y sólo cuando la lectura de una señal en el plantilla notifique a Angular que su valor a cambiado".</p><p>Aquí un ejemplo para ilustrar el proceso. Digamos que hay algo de trabajo realizándose dentro del método (mostrado abajo) que busca ajustar la cantidad. Digamos que quizá el caso de uso podría ser algo como una promoción, que si por ejemplo el usuario elige una cantidad igual o mayor a 5 entonces se lleva uno gratis. El punto es que la señal <code>cantidad</code> podría cambiar en varias ocasiones durante la ejecución del método.</p><pre><code class="language-typescript">alSeleccionarCantidad(cant: number) {
  this.cantidad.set(qty);
  
  this.cantidad.set(5);
  this.cantidad.set(42);
}</code></pre><p>La cantidad se muestra en la plantilla usando la vinculación de Angular (binding) como se muestra abajo. Ya que el vínculo "lee" la señal <code>cantidad</code>, la plantilla "registra" su interés en recibir notificaciones de cambios. </p><pre><code class="language-html">//Angular binding (vinculación en la plantilla)
{{ cantidad() }}</code></pre><p>Cuando el usuario elige la cantidad el método <code>alSeleccionarCantidad()</code> se ejecuta. El código en este método primero asigna el valor seleccionado por el usuario a la señal <code>cantidad</code>. Luego cuando la nueva señal se asigna esta genera una notificación. En este punto, se agenda la ejecución del mecanismo de detección de cambios de Angular, pero no tiene la oportunidad de hacerlo sino hasta después de la ejecución del método <code>alSeleccionarCantidad()</code>. &nbsp; </p><p>Entonces, el método <code>alSeleccionarCantidad()</code> continúa asignando el número <code>5</code> a la señal, que genera otra notificación de cambio. De nuevo el mecanismo de detección de cambios de Angular es llamado a ejecutarse pero aún debe esperar a que el método <code>alSeleccionarCantidad()</code> termine su ejecución. El método entonces asigna el valor <code>42</code> a la señal y el proceso se repite.</p><p>Cuando se completa la ejecución del método <code>alSeleccionarCantidad()</code> finalmente será turno de ejecución del mecanismo de detección de cambios de Angular. La plantilla lee la señal y obtiene su valor, que es <code>42</code>. La plantilla no es "consciente" de ninguno de los valores anteriores. La vista se vuelve a "renderizar" y el nuevo valor de la señal <code>cantidad</code> se mostrará. </p><p>Si la señal cambia, cualquier "consumidor" interesado en su lectura será notificado. Pero el consumidor no recibirá el nuevo valor, sino que, hasta la próxima vez, cuando sea el turno de ejecución del consumidor es entonces que podrá "leer" el valor actual de la señal.</p><p>Si conoces cómo funcionan los observables en RxJS podrás notar que las señales pueden ser distintas ya que no emiten valores cómo lo hacen los observables, además de que no requieren una suscripción.</p><p>Además del método <code>set()</code>, también hay otras 2 maneras de cambiar una señal: <code>update()</code> y <code>mutate()</code>. El método <code>set()</code> reemplaza el valor de una señal con un valor nuevo, metafóricamente remplazado el contenido del "cajón" de la señal. Pásale el nuevo valor al método <code>set()</code>.</p><pre><code class="language-typescript">// Remplaza el valor
this.cantidad.set(cant);</code></pre><p>El método <code>update()</code> actualiza la señal en base a su valor actual. Pasa una función de "flecha" al método <code>update()</code>, esta provee el valor actual de la señal para que sea posible cambiarlo programáticamente según sea necesario. En el siguiente código la cantidad se duplica.</p><pre><code class="language-typescript">// Actualizar el valor de la señal en base al valor actual
this.cantidad.update(cant =&gt; cant * 2);</code></pre><p>El método <code>mutate()</code> modifica el contenido del valor de una señal, no el valor de la señal en sí. Úsalo con arreglos para modificar sus elementos y con objetos para modificar sus propiedades. En la siguiente línea de código se incrementa 20% el precio de un vehículo. </p><pre><code class="language-typescript">this.vehiculoSeleccionado.mutate(v =&gt; v.precio = v.precio + (v.precio * .20));</code></pre><p>Independientemente de la forma en cómo se modifica la señal, los consumidores serán notificados que ha sucedido un cambio, ellos pueden entonces leer el nuevo valor de la señal cuando es su turno de ejecución.</p><h2 id="c-mo-definir-una-se-al-computada"><strong>Cómo definir una señal computada</strong></h2><p>Frecuentemente tenemos variables en nuestro código que dependen de otras variables, por ejemplo, el precio total de un ítem es su precio unitario por el número o cantidad de ítems deseados de este tipo. Si el usuario cambia la cantidad queremos también cambiar el precio total, para lo que utilizamos <strong>señales computadas</strong> (<strong><strong>computed signals</strong></strong>). </p><p>Define una señal computada llamando la función <code>computed()</code> de creación de señales computadas, esta crea una nueva señal que depende de otras. Ahora pasemos a la función <code>computed()</code> una función que lleve a cabo las operaciones deseadas, esta tendrá acceso a la lectura de el valor de una o más señales para llevar a cabo su computo.</p><pre><code class="language-typescript">precioTotal = computed(() =&gt; this.vehiculoSeleccionado().precio * this.cantidad());

color = computed(() =&gt; this.precioTotal() &gt; 50000 ? 'verde' : 'azul');</code></pre><p>La primera línea de código de arriba define una señal computada <code>precioTotal</code> al llamar la función de creación <code>computed()</code>, la función que pasamos a esta función lee las señales <code>vehiculoSeleccionado</code> y <code>cantidad</code>, si cualquiera de estas cambia, la señal computada será notificada y leerá el nuevo valor la próxima vez que se ejecute.</p><p>La segunda línea define la señal computada <code>color</code>, que le asigna el valor <code>verde</code>o <code>azul</code> dependiendo del valor de la señal <code>precioTotal</code>. La plantilla puede vincular a esta señal para mostrar el estilo apropiado. </p><p>Una señal computada es sólo lectura y no puede ser modificada con los métodos <code>set()</code>, <code>update()</code> ni <code>mutate()</code>, además su valor se re-evalúa o re-computa cuando:</p><ul><li>Uno o más de sus señales dependientes ha cambiado.</li><li>Y el valor de la señal computada ha sido leído.</li></ul><p>La señal computada se "<em>memoiza", </em>lo que quiere decir que guarda el resultado evaluado, este es re-utilizado la próxima vez que es leído.</p><p>Digamos por ejemplo que tenemos lo siguiente en nuestra plantilla:</p><pre><code class="language-typescript">Precio extendido: {{ precioTotal() }}
Precio total: {{ precioTotal() }}
Cantidad a pagar: {{ precioTotal() }}</code></pre><p>La primera vez que la plantilla lea la señal computada <code>precioTotal</code>, el valor se calcula y se guarda en memoria, las siguientes 2 veces que se lee, se re-utiliza el valor almacenado anteriormente. Dicho valor no se re-calcula a menos que alguna de sus señales dependientes haya cambiado.</p><h2 id="c-mo-usar-un-efecto"><strong>Cómo usar un efecto</strong></h2><p>Podría haber momentos en que necesites ejecutar código en respuesta al cambio de alguna señal y que este código tenga efectos secundarios, por ello quiero decir que este código haga un llamado a alguna API o que realice alguna otra operación no relacionada a la señal, en estos casos debemos usar <code>effect()</code>. </p><p>Por ejemplo, digamos que quieres inspeccionar tu código en busca de errores (debug) y para ello deseas imprimir el valor de la señal usando <code>console.log</code> cada vez que esta sufra un cambio, como sabemos llamar <code>console.log</code> es un efecto secundario. </p><p>Para definir un efecto debemos llamar la función creacional <code>effect()</code>. Pasémosle a esta función la operación a realizar, la cual será ejecutada nuevamente cada vez que el código reaccione a un cambio en cualquiera de la señales dependientes.</p><pre><code class="language-typescript">effect(() =&gt; console.log(this.vehiculoSeleccionado()));</code></pre><p>La función <code>effect()</code> puede ser invocada desde otra función, pero frecuentemente es llamada desde el constructor u otro código de inicialización, dado que a su vez prepara un tipo de función manejadora (handler).</p><p>Alternativamente un efecto puede definirse de forma declarativa como se muestra a continuación:</p><pre><code class="language-typescript">e = effect(() =&gt; console.log(this.vehiculoSeleccionado()));</code></pre><p>Un efecto no debería cambiar el valor de ninguna señal, sin embargo si necesitas cambiar una señal en base a un cambio a otra señal dependiente es recomendable que utilices una señal computada en su lugar.</p><p>Cómo verás, no es muy común utilizar los efectos, aunque son útiles para imprimir valores por consola o para llamar APIs externas, pero no los uses para trabajar con RxJS ni Observables; habrá funcionalidades de las señales que serán útiles para convertir a y desde los observables.</p><h2 id="cu-ndo-usar-se-ales"><strong>Cuándo usar señales</strong></h2><p>Algunas sugerencias.</p><p>En primer lugar, continúa utilizando "handlers" en tus componentes como has venido haciendo hasta ahora para manejar o responder a las acciones de los usuarios. Acciones como realizar una selección de una lista desplegable, hacer clic en un botón o ingresar datos en una "caja de texto".</p><p>Usa una señal o señal computada en un componente para cualquier estado que pueda cambiar. En este contexto, estado se refiere a cualquier dato que sea administrado por el componente. Cualquier cosas desde una bander <code>estaCargandose</code> hasta la página actualmente mostrada con los datos seleccionados por el usuario podrían ser señales. Las señales son especialmente útiles cuando se muestran los datos en la plantilla que deben reaccionar a cambios dependientes de otras acciones.</p><p>Las señales compartidas deberían ser servicios. Digamos que tenemos un arreglo con los vehículos devueltos que se comparte entre componentes, este podría ser un servicio.</p><p>Continúa usando los observables para operaciones asíncronas como las llamadas a <code>http.get()</code>, cabe mencionar que hay otras funcionalidades que vendrán con las señales para equiparar más fielmente con los observables.</p><h2 id="concluyendo"><strong>Concluyendo</strong></h2><p>Las señales representan un avance mayúsculo en las capacidades de programación reactiva y detección de cambios de Angular. Este tutorial respondió a las preguntas: "¿Por qué?", "¿Qué?" y "¿Cómo?" así como "¿Dónde?" y "¿Cuándo?" también.</p><p>Las señales están disponibles en vista previa para desarrolladores en Angular v16, como parte de esta vista previa las señales se incluyen en el modelo de detección de cambios. Se espera que futuras capacidades de las señales mejorarán la detección de cambios y marcarán los componentes para revisión de una forma similar como se lleva a cabo actualmente al usar <code>OnPush</code> con la pipa asíncrona (async pipe). &nbsp;</p><p>Una forma sencilla y fácil de probar las señales es usar Stackblitz que es un editor de código en línea que trabaja muy bien con Angular y no requiere instalaciones. Para usar Stackblitz con señales:</p><ol><li>Navega al sitio de Stackblitz: <a href="http://www.stackblitz.com/">www.stackblitz.com</a>.</li><li>Haz clic en el icono de Angular para crear un proyecto Angular.</li><li>Edita el archivo <code>package.json</code> resultante y cambia las versiones de los paquetes de @angular a sus versiones más actuales "pre-realease" (Angular v16).</li><li>Guarda el proyecto para que se actualicen las dependencias.</li><li>Dale una probada a las señales.</li></ol><p>Para ver estos pasos en acción dale un vistazo al final del siguiente vídeo (en inglés):</p><figure class="kg-card kg-embed-card" data-test-label="fitted">
        <div class="fluid-width-video-container">
          <div style="padding-top: 56.17977528089888%;" class="fluid-width-video-wrapper">
            <iframe width="356" height="200" src="https://www.youtube.com/embed/oqYQG7QMdzw?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen="" title="Angular Signals: What? Why? and How?" name="fitvid1" style="box-sizing: inherit; margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 22px; vertical-align: middle; position: absolute; top: 0px; left: 0px; width: 720px; height: 404.489px;"></iframe>
          </div>
        </div>
      </figure><p>También puedes empezar usando el enlace a mi proyecto <a href="https://stackblitz.com/edit/angular-signals-deborahk">https://stackblitz.com/edit/angular-signals-deborahk</a>. Asegúrate de crear una copia para que puedas realizar tus propios cambios.</p><p>¡Las señales llegaron! Van a mejorar la capacidad de detección de cambios y la reactividad de tu código, además de hacerlo de más fácil edición y lectura, además que son muy divertidas de usar. </p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Consumiendo servicios API desde Javascript ]]>
                </title>
                <description>
                    <![CDATA[ Cuando desarrollamos para la web, es una tarea común y crítica, el consumo de servicios de datos, que serán parte fundamental de nuestra aplicación. Siendo que JavaScript es el lenguaje que usamos para dar interactividad, revisemos como consumir APIs desde nuestras aplicaciones web, para obtener y manipular datos de forma ]]>
                </description>
                <link>https://www.freecodecamp.org/espanol/news/consumiendo-servicios-api-desde-javascript/</link>
                <guid isPermaLink="false">671bb58f408801043e04ba54</guid>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Leonardo José Castillo Lacruz ]]>
                </dc:creator>
                <pubDate>Wed, 30 Oct 2024 13:06:08 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/espanol/news/content/images/2024/10/Youtube--11-.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Cuando desarrollamos para la web, es una tarea común y crítica, el consumo de servicios de datos, que serán parte fundamental de nuestra aplicación. Siendo que JavaScript es el lenguaje que usamos para dar interactividad, revisemos como consumir APIs desde nuestras aplicaciones web, para obtener y manipular datos de forma dinámica. En las siguientes líneas vamos a verificar cómo funcionan las solicitudes HTTP, el uso de <code>fetch</code> y el papel de <code>async/await</code> en el consumo de APIs. Usaremos la API de <a href="https://restcountries.com/" rel="noopener">REST Countries</a> como ejemplo, permitiéndonos acceder y mostrar datos detallados sobre países en una aplicación interactiva.</p><h2 id="introducci-n-a-las-apis-y-rest">Introducción a las APIs y REST</h2><h3 id="-qu-es-una-api">¿Qué es una API?</h3><p>API, o <em>Interfaz de Programación de Aplicaciones</em> (Application Programming Interface), es un conjunto de reglas y protocolos que permite que dos aplicaciones se comuniquen entre sí. Piensa en una API como un puente que conecta dos aplicaciones: una puede pedirle datos o servicios a otra sin necesidad de conocer su funcionamiento interno.</p><h3 id="-qu-es-rest">¿Qué es REST?</h3><p>REST, o <em>Transferencia de Estado Representacional</em> (Representational State Transfer), es un estilo arquitectónico para diseñar APIs. Las APIs REST suelen usar URLs para identificar recursos (como países, en nuestro caso) y métodos HTTP (GET, POST, PUT, DELETE) para definir las acciones a realizar sobre esos recursos.</p><h2 id="m-todos-http-en-el-consumo-de-apis">Métodos HTTP en el Consumo de APIs</h2><p>Las APIs REST se basan en el protocolo HTTP, el cual es el mismo protocolo que usamos al navegar en la web. Cada acción que llevamos a cabo con la API (consultar datos, crear un nuevo registro, actualizar o eliminar un registro) se representa a través de un <strong>método HTTP</strong>. Estos métodos son parte integral de la arquitectura REST, ya que permiten manipular recursos de forma estandarizada.</p><p>Cada método HTTP tiene un propósito específico y su propio rol en la interacción con la API:</p><p><strong>GET</strong>: Este es el método más común y se usa para <em>recuperar datos</em> de un recurso específico. Es como una consulta de solo lectura; no cambia ni afecta el estado de los datos en el servidor.</p><ul><li><strong>Ejemplo</strong>: Al consultar la API para obtener una lista de países, usamos una solicitud GET.</li></ul><p><strong>POST</strong>: Este método se utiliza para <em>enviar datos</em> al servidor y crear un nuevo recurso en él. A diferencia de GET, POST modifica el estado del servidor al agregar datos.</p><ul><li><strong>Ejemplo</strong>: En una API de usuarios, un POST a la URL <code>https://api.ejemplo.com/usuarios</code> podría crear un nuevo usuario en la base de datos.</li></ul><p><strong>PUT</strong>: Se usa para <em>actualizar un recurso existente</em> en el servidor. En general, se espera que una solicitud PUT contenga todos los datos del recurso a actualizar, y reemplaza el recurso en el servidor con los datos enviados.</p><ul><li><strong>Ejemplo</strong>: Actualizar los detalles de un país en la base de datos mediante una solicitud PUT a <code>https://api.ejemplo.com/paises/{id}</code>.</li></ul><p><strong>DELETE</strong>: Este método se utiliza para <em>eliminar un recurso específico</em> en el servidor. Como su nombre lo indica, DELETE quita o borra datos de la base de datos o sistema remoto.</p><ul><li><strong>Ejemplo</strong>: Una solicitud DELETE a <code>https://api.ejemplo.com/usuarios/{id}</code> eliminaría al usuario con el ID especificado.</li></ul><p>Cada uno de estos métodos se representa en las aplicaciones REST de forma clara, permitiendo a los desarrolladores y al servidor entender qué acción se desea realizar sobre los datos. Estos métodos, cuando se usan con <code>fetch</code> en JavaScript, nos permiten manipular y gestionar datos de manera precisa y efectiva en la aplicación.</p><h3 id="ejemplo-de-solicitudes-http-con-fetch">Ejemplo de Solicitudes HTTP con <code>fetch</code></h3><p>El método <code>fetch</code> en JavaScript nos permite implementar fácilmente cualquiera de estos métodos HTTP:</p><ul><li><strong>GET</strong>: Para recuperar datos, pasamos solo la URL a <code>fetch</code>.</li><li><strong>POST, PUT y DELETE</strong>: Estos métodos requieren configuraciones adicionales en <code>fetch</code>, como el tipo de método, los encabezados y el cuerpo de la solicitud.</li></ul><h2 id="uso-de-fetch-en-javascript">Uso de <code>fetch</code> en JavaScript</h2><p><code>fetch</code> es una función nativa en JavaScript que facilita el envío de solicitudes HTTP, devolviendo una <em>promesa</em>. Usar <code>fetch</code> con <code>async/await</code> mejora la legibilidad del código y simplifica la gestión de las respuestas, lo que es especialmente útil cuando trabajamos con datos de una API.</p><h3 id="estructura-b-sica-de-fetch">Estructura Básica de <code>fetch</code></h3><p>La sintaxis básica de <code>fetch</code> para una solicitud GET es:</p><pre><code>fetch(url)
    .then(response =&gt; response.json())
    .then(data =&gt; console.log(data))
    .catch(error =&gt; console.error('Error:', error));
</code></pre><p>O usando <code>async/await</code>:</p><pre><code class="language-Javascript">async function getData(url) {
    try {
        const response = await fetch(url);
        const data = await response.json();
        console.log(data);
    } catch (error) {
        console.error('Error:', error);
    }
}
</code></pre><h3 id="solicitud-get-con-fetch">Solicitud GET con <code>fetch</code></h3><p>En una solicitud GET, simplemente se pasa la URL de la API a <code>fetch</code>. Nuestro ejemplo utiliza este método para obtener datos de países según su subregión.</p><pre><code>async function getDatos(subregion) {
    try {
        const res = await fetch(`https://restcountries.com/v3.1/subregion/${subregion}`);
        const data = await res.json();
        dibujaCards(data);
    } catch (error) {
        alert('No pude conectarme a la API');
    }
}
</code></pre><h3 id="solicitud-post-put-y-delete-con-fetch">Solicitud POST, PUT y DELETE con <code>fetch</code></h3><p>Para otras operaciones (POST, PUT, DELETE), podemos añadir una configuración adicional a <code>fetch</code>, especificando el método, encabezados y el cuerpo de la solicitud.</p><h4 id="ejemplo-de-post">Ejemplo de POST</h4><p>Un ejemplo típico de POST podría ser enviar datos a una API para crear un nuevo recurso, como un usuario.</p><pre><code>async function createUser(userData) {
    try {
        const response = await fetch('https://example.com/api/users', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json'
            },
            body: JSON.stringify(userData)
        });
        const data = await response.json();
        console.log('Usuario creado:', data);
    } catch (error) {
        console.error('Error al crear usuario:', error);
    }
}
</code></pre><h4 id="ejemplo-de-put">Ejemplo de PUT</h4><p>PUT se usa para actualizar un recurso existente. Este ejemplo muestra cómo modificar los datos de un usuario:</p><pre><code>async function updateUser(userId, updatedData) {
    try {
        const response = await fetch(`https://example.com/api/users/${userId}`, {
            method: 'PUT',
            headers: {
                'Content-Type': 'application/json'
            },
            body: JSON.stringify(updatedData)
        });
        const data = await response.json();
        console.log('Usuario actualizado:', data);
    } catch (error) {
        console.error('Error al actualizar usuario:', error);
    }
}
</code></pre><h4 id="ejemplo-de-delete">Ejemplo de DELETE</h4><p>Para eliminar un recurso, simplemente usamos el método DELETE y la URL correspondiente.</p><pre><code>async function deleteUser(userId) {
    try {
        const response = await fetch(`https://example.com/api/users/${userId}`, {
            method: 'DELETE'
        });
        if (response.ok) {
            console.log('Usuario eliminado');
        }
    } catch (error) {
        console.error('Error al eliminar usuario:', error);
    }
}
</code></pre><h2 id="proyecto-explorador-de-pa-ses">Proyecto: Explorador de Países</h2><p>Vamos a crear una pequeña aplicación, que consuma datos de la API de <a href="https://restcountries.com/" rel="noopener">REST Countries</a> y poder generar una presentación de galería, así como una presentación de detalle por país, con ello vamos a poder poner en práctica los conceptos anteriormente explicados.</p><figure class="kg-card kg-embed-card" data-test-label="fitted">
        <div class="fluid-width-video-container">
          <div style="padding-top: 56.49999999999999%;" class="fluid-width-video-wrapper">
            <iframe width="200" height="113" src="https://www.youtube.com/embed/cb5BIStLYv4?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" title="Crea una Galería de Países en JavaScript: Consume APIs REST y Muestra Mapas con OpenStreetMap!" name="fitvid0"></iframe>
          </div>
        </div>
      </figure><h2 id="proyecto-explorador-de-pa-ses-1">Proyecto: Explorador de Países</h2><p>El proyecto está compuesto por:</p><ol><li><strong>HTML (<code>index.html</code>)</strong>: Define la estructura de la aplicación.</li><li><strong>JavaScript (<code>script.js</code>)</strong>: Realiza la solicitud a la API para obtener datos de países según la subregión seleccionada.</li><li><strong>HTML (</strong><code><strong>detail.html</strong></code><strong>)</strong>: Define la estructura de la presentación de detalle del país.</li><li><strong>JavaScript de Detalle (<code>detail.js</code>)</strong>: Muestra detalles específicos de un país.</li></ol><h3 id="html-de-la-p-gina-principal">HTML de la Página Principal</h3><p>En el archivo <code>index.html</code>, configuramos una barra de navegación para seleccionar una subregión (América del Norte, América del Sur o América Central) y una galería donde se muestran los países.</p><pre><code>&lt;nav&gt;
    &lt;ul class="navbar"&gt;
        &lt;li&gt;&lt;a href="#norteamerica"&gt;América del Norte&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href="#suramerica"&gt;América del Sur&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href="#centroamerica"&gt;América Central&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
&lt;/nav&gt;
&lt;div id="loading" class="loading hidden"&gt;Cargando...&lt;/div&gt;
&lt;section class="gallery"&gt;&lt;/section&gt;
&lt;footer&gt;
    &lt;p&gt;&amp;copy; 2024 América - Explorando Países&lt;/p&gt;
&lt;/footer&gt;
</code></pre><h3 id="funci-n-para-obtener-datos-en-script-js">Función para Obtener Datos en <code>script.js</code></h3><p>Aquí, <code>fetch</code> se usa para hacer una solicitud GET a la API y obtener datos sobre países de una subregión. Se muestra un indicador de carga durante la consulta y se actualiza la galería una vez que se reciben los datos.</p><pre><code>const loadingIndicator = document.getElementById('loading');

function showLoading() {
    loadingIndicator.classList.remove('hidden');
}

function hideLoading() {
    loadingIndicator.classList.add('hidden');
}

async function getDatos(subregion) {
    try {
        showLoading();
        const res = await fetch(`https://restcountries.com/v3.1/subregion/${subregion}`);
        const data = await res.json();
        dibujaCards(data);
    } catch (error) {
        alert('No pude conectarme a la API');
    } finally {
        hideLoading();
    }
}
</code></pre><h3 id="funci-n-dibujacards-paises-">Función <code>dibujaCards(paises)</code></h3><p>Esta función recibe los datos de la API y los muestra en una tarjeta HTML para cada país.</p><pre><code>function dibujaCards(paises) {
    const galeria = document.querySelector('.gallery');
    let htmlPaises = '';
    paises.forEach((pais) =&gt; {
        htmlPaises += `
        &lt;div class="card"&gt;
            &lt;h2&gt;${pais.name.official}&lt;/h2&gt;
            &lt;p&gt;&lt;strong&gt;Capital:&lt;/strong&gt; ${pais.capital ? pais.capital[0] : 'No Disponible'}&lt;/p&gt;
            &lt;p&gt;&lt;strong&gt;Idioma:&lt;/strong&gt; ${Object.values(pais.languages || { '': 'No Disponible' }).join(', ')}&lt;/p&gt;
            &lt;button onclick="viewMore('${pais.cca3}')"&gt;Ver más&lt;/button&gt;
        &lt;/div&gt;
        `;
    });
    galeria.innerHTML = htmlPaises;
}
</code></pre><h2></h2><p>Resumiendo lo realizado, &nbsp;<code>fetch</code> y <code>async/await</code> nos brindan una forma poderosa y sencilla de consumir APIs en JavaScript. Al conocer los diferentes métodos HTTP y cómo configurarlos en <code>fetch</code>, ahora tienes las bases para manejar solicitudes <code>GET</code>, <code>POST</code>, <code>PUT</code> y <code>DELETE</code>, lo cual te abrirá muchas posibilidades para crear aplicaciones interactivas que consuman o modifiquen datos de forma dinámica.</p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Cómo acceder a las propiedades de un arreglo de objetos en JavaScript ]]>
                </title>
                <description>
                    <![CDATA[ Al trabajar con aplicaciones de JavaScript, es común hacerlo con arreglos,  arreglos anidados, y con arreglos de objetos. Sin embargo, muchos principiantes no saben cómo acceder a las propiedades de estas estructuras de datos. En este artículo, vamos a hablar sobre cómo acceder a las propiedades de una variedad ]]>
                </description>
                <link>https://www.freecodecamp.org/espanol/news/como-acceder-a-las-propiedades-de-un-arreglo-de-objetos-en-javascript/</link>
                <guid isPermaLink="false">6643b40b66e68c03ffefd7e5</guid>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Constanza Areal ]]>
                </dc:creator>
                <pubDate>Tue, 30 Jul 2024 12:55:14 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/espanol/news/content/images/2024/07/david-rangel-4m7gmLNr3M0-unsplash.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Al trabajar con aplicaciones de JavaScript, es común hacerlo con <em>arreglos</em>,<em> arreglos</em> anidados, y con arreglos de objetos. Sin embargo, muchos principiantes no saben cómo acceder a las propiedades de estas estructuras de datos.</p><p>En este artículo, vamos a hablar sobre cómo acceder a las propiedades de una variedad de arreglos y ver algunos ejemplos de código. </p><h2 id="-qu-es-un-arreglo-en-javascript"><strong>¿Qué es un arreglo en JavaScript?</strong></h2><p>Un arreglo<em> </em>es un tipo de estructura de datos de JavaScript que se usa para almacenar una colección de elementos de distintas clases.</p><p>Es posible tener un arreglo de cadenas de texto, como este:</p><pre><code class="language-js">const fruits = ["apple", "banana", "mango", "orange"];
</code></pre><p>O un arreglo de números:</p><pre><code class="language-js">const numbers = [1, 2, 3, 4, 5];
</code></pre><p>y hasta un arreglo anidado de arreglos como este:</p><pre><code class="language-js">const nestedArray = [
  [1, 2, 3],
  [4, 5, 6],
  [7, 8, 9],
];
</code></pre><p>También es posible tener un arreglo<em> </em>de distintas clases de datos:</p><pre><code class="language-js">const mixedArray = ["apple", 1, "banana", 2, "mango", 3];
</code></pre><h2 id="c-mo-acceder-a-los-elementos-de-un-arreglo-en-javascript-"><strong>Cómo acceder a los elementos de un </strong>arreglo<strong> en JavaScript:</strong></h2><p>Para acceder a un elemento de un arreglo, hay que referenciar el nombre del arreglo<em>,</em> seguido del número de índice del elemento que queremos acceder, entre corchetes.</p><p>Este es un ejemplo de cómo acceder al primer elemento del arreglo <code>fruits</code>:</p><pre><code class="language-js">const fruits = ["apple", "banana", "mango", "orange"];
console.log(fruits[0]); // apple
</code></pre><p>Los arreglos siempre comienzan en cero. Esto significa que el primer elemento tiene el índice 0, el segundo tiene el 1 y así los siguientes elementos.<br><br>Para acceder al último elemento del arreglo, se puede usar la longitud (<em>length</em>) del arreglo menos 1.</p><pre><code class="language-js">const fruits = ["apple", "banana", "mango", "orange"];
console.log(fruits[fruits.length - 1]); // orange
</code></pre><p>A veces puede ser confuso cuando se está trabajando con un arreglo anidado de arreglos, pero la sintaxis es la misma que usamos cuando queremos acceder a un elemento de un arreglo anidado. Por ejemplo, si queremos acceder al primer elemento de <code>nestedArray</code>: </p><pre><code class="language-js">const nestedNumberArray = [
  [1, 2, 3],
  [4, 5, 6],
  [7, 8, 9],
];
console.log(nestedNumberArray[0][0]); // 1
</code></pre><p><code>nestedNumberArray[0]</code> apunta a este arreglo:</p><pre><code class="language-js">[1, 2, 3];
</code></pre><p>Para acceder al primer elemento de este arreglo, hay que usar otro para de corchetes con el número de índice que se quiere acceder:</p><pre><code class="language-js">nestedNumberArray[0][0];
</code></pre><h2 id="c-mo-acceder-a-las-propiedades-de-un-arreglo-de-objetos-en-javascript"><strong>Cómo acceder a las propiedades de un arreglo de objetos en JavaScript</strong></h2><p>Muchas veces vamos a encontrar arreglos de objetos en JavaScript.</p><p>En este ejemplo, dentro del <em>arreglo</em> <code>developers</code>, cada desarrollador tiene las siguientes propiedades: <em>name</em>, <em>age</em> y la propiedad <em>languages </em>que es un <em>arreglo </em>con los lenguajes de programación que conocen.</p><pre><code class="language-js">const developers = [
  { name: "John", age: 25, languages: ["JavaScript", "Python"] },
  { name: "Kelly", age: 37, languages: ["Ruby", "Python", "C", "C++"] },
  { name: "Zack", age: 45, languages: ["Go", "C#"] },
];</code></pre><p>Si queremos acceder a la propiedad <em>name </em>del primer desarrollador, usamos la siguiente sintaxis:</p><pre><code class="language-js">console.log(developers[0].name); // John
</code></pre><p>Aquí estamos usando una combinación de anotación de punto y corchetes para acceder a la primera propiedad del objeto del primer desarrollador en el <em>arreglo</em> <code>developers</code>.</p><p><code>developers[0]</code> es el objeto del primer desarrollador.</p><pre><code class="language-js">{ name: "John", age: 25, languages: ["JavaScript", "Python"] }
</code></pre><p>Luego usamos la notación de punto (<code>developers[0].name</code>) para acceder a la propiedad <code>name</code> de este objeto.</p><h2 id="c-mo-encontrar-un-valor-espec-fico-de-un-arreglo-de-objetos-en-javascript"><strong>Cómo encontrar un valor específico de un arreglo de objetos en JavaScript</strong></h2><p>Para buscar un objeto en particular dentro de un <em>arreglo </em>de objetos, es posible usar el método <code>find</code>. Este método devuelve el primer elemento en el <em>arreglo</em> que cumple con los parámetros de la función. Si ningún elemento los cumple, devuelve <code>undefined</code>.</p><p>Este es un ejemplo usando el método <code>find</code> con un <em>arreglo</em> de números:</p><pre><code class="language-js">const numbers = [1, 2, 3, 4, 5];

const foundNumber = numbers.find((number) =&gt; number &gt; 3); // 4
</code></pre><p>En el ejemplo anterior, el método <code>find</code> busca entre los números del <em>arreglo</em> y devuelve el primer número mayor a 3. En este caso, <code>find</code> devuelve el número 4.</p><p>También podemos usar el mismo razonamiento para encontrar un objeto específico dentro de un <em>arreglo</em> de objetos.</p><p>En el siguiente ejemplo, vamos a buscar el objeto con el valor "Kelly" en la propiedad <code>name</code> dentro del arreglo <code>developers</code>.</p><pre><code class="language-js">const developers = [
  { name: "John", age: 25, languages: ["JavaScript", "Python"] },
  { name: "Kelly", age: 37, languages: ["Ruby", "Python", "C", "C++"] },
  { name: "Zack", age: 45, languages: ["Go", "C#"] },
];

developers.find((developer) =&gt; developer.name === "Kelly");
</code></pre><p>En este ejemplo, <code>developer</code> representa cada objeto del <em>arreglo</em>. El método <code>find</code> va a recorrer el <em>arreglo</em> <code>developers</code> y devolver el primer objeto <code>developer</code> que tenga el valor "Kelly" en la propiedad <code>name</code>.</p><pre><code class="language-js">{ name: "Kelly", age: 37, languages: ["Ruby", "Python", "C", "C++"] }
</code></pre><h2 id="conclusi-n"><strong>Conclusión</strong></h2><p>Espero que este artículo te haya resultado útil para aprender sobre <em>arreglos </em>y cómo acceder a sus propiedades.</p><p>Vimos un par de ejemplos de <em>arreglos</em> y también vimos cómo acceder a sus elementos desde <em>arreglos </em>anidados y de un <em>arreglo</em> de objetos.</p><p>También aprendimos el método <code>find</code> y cómo usarlo para encontrar un objeto específico dentro de un <em>arreglo</em> de objetos.</p><p>Ahora deberías poder entender mejor sobre cómo trabajar con <em>arreglos</em> y objetos en JavaScript.</p><p>¡Feliz codificación! 🚀</p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Cómo usar los Objetos Map y Set de JavaScript: Explicado con ejemplos de código ]]>
                </title>
                <description>
                    <![CDATA[ Map y Set son dos estructuras de datos de JavaScript que puedes usar para almacenar una colección de valores, similares a los Objetos y Arreglos. Son estructuras de datos especializados que te pueden ayudar en almacenar y manipular valores relativos. En este tutorial, veremos cómo funcionan Map y Set en ]]>
                </description>
                <link>https://www.freecodecamp.org/espanol/news/como-usar-los-objetos-map-y-set-de-javascript-explicado-con-ejemplos-de-codigo/</link>
                <guid isPermaLink="false">66912627b99552046f705c9f</guid>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Elias Ezequiel Pereyra Gomez ]]>
                </dc:creator>
                <pubDate>Mon, 29 Jul 2024 21:07:08 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/espanol/news/content/images/2024/07/javascript-mat-and-set-objects-introduction.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-map-and-set-objects-explained/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">How to Use the JavaScript Map and Set Objects – Explained with Code Examples</a>
      </p><p>Map y Set son dos estructuras de datos de JavaScript que puedes usar para almacenar una colección de valores, similares a los Objetos y Arreglos. Son estructuras de datos especializados que te pueden ayudar en almacenar y manipular valores relativos.</p><p>En este tutorial, veremos cómo funcionan Map y Set en detalle y saber cuándo usarlos. También exploraremos los métodos de composición de objetos de Set que fueron agregados recientemente al estándar de JavaScript.</p><h2 id="tabla-de-contenidos"><strong>Tabla de Contenidos</strong></h2><ul><li><a href="#objecto-map-explicado">El Objeto Map explicado</a></li><li><a href="#como-crear-objeto-map">Cómo crear un objeto Map</a></li><li><a href="#metodos-propiedades-objeto-map">Métodos y Propiedes de un Objeto Map</a> </li><li><a href="#otras-formas-crear-objeto-map">Otras formas de crear un Objeto Map</a></li><li><a href="#iterar-datos-objeto-map">Iterar sobre datos del Objeto Map</a></li><li><a href="#cuando-usar-objeto-map">Cuándo usar el Objeto Map</a></li><li><a href="#objeto-set-explicado">El Objeto Set explicado</a></li><li><a href="#como-crear-objeto-set">Cómo crear un Objeto Set</a></li><li><a href="#metodos-propiedades-objeto-set">Métodos y Propiedades del Objeto Set</a></li><li><a href="#metodos-composicion-set">Métodos de Composición de Set</a></li><li><a href="#iterar-objeto-set">Iterar sobre un Objeto Set</a></li><li><a href="#cuando-usar-objeto-set">Cuándo usar el Objeto Set</a></li><li><a href="#conclusion">Conclusión</a></li></ul><!--kg-card-begin: html--><h2 id="objecto-map-explicado">El Objeto Map explicado</h2><!--kg-card-end: html--><p>El objeto <code>Map</code> almacena los datos en una estructura de par clave/valor, así como un Objeto. Las principales diferencias entre un objeto regular y un <code>Map</code> son: </p><ul><li>Un objeto <code>Map</code> puede tener cualquier tipo de datos como el valor clave</li><li>Un objeto <code>Map</code> mantiene el orden de los datos agregados al objeto</li></ul><!--kg-card-begin: html--><h3 id="como-crear-objeto-map">Cómo crear un Objeto Map</h3><!--kg-card-end: html--><p>Para crear un objeto <code>Map</code>, puedes llamar al constructor <code>Map()</code> de esta forma:</p><figure class="kg-card kg-code-card"><pre><code class="language-js">const myMap = new Map();</code></pre><figcaption>Crea un objeto Map en JavaScript</figcaption></figure><p>El código de arriba crea un nuevo objeto <code>Map</code> vacío.</p><!--kg-card-begin: html--><h3 id="metodos-propiedades-objeto-map">Métodos y Propiedades de un Objeto Map</h3><!--kg-card-end: html--><p>Un objeto <code>Map</code> tiene los siguientes métodos y propiedades:</p><ul><li><code>set(key, value)</code> – Agrega un par clave/valor a un Map</li><li><code>get(key)</code> – Devuelve un valor desde un Map (regresa <code>undefined</code> si la clave no existe)</li><li><code>has(key)</code> – Verifica si un Map tiene una clave específica</li><li><code>delete(key)</code> – Quita una clave específica desde un Map</li><li><code>clear()</code> – Quita todos los elementos de un Map</li><li><code>keys()</code> – Devuelve todas las claves en un Map</li><li><code>values()</code> – Devuelve todos los valores en un Map</li><li><code>entries()</code> – Devuelve todas las claves y valores en un Map</li><li><code>size</code> – Devuelve el número de items de un Map</li></ul><p>Para insertar datos en el objeto <code>Map</code>, puedes usar el método <code>set()</code>:</p><figure class="kg-card kg-code-card"><pre><code class="language-js">const myMap = new Map();

myMap.set(1, 'Jack');
myMap.set(2, 'Jill');
myMap.set('animal', 'Elefante');</code></pre><figcaption>Insertando valores al objeto Map</figcaption></figure><p>El código de arriba crea un objeto <code>Map</code> con 3 entradas de la siguiente forma:</p><figure class="kg-card kg-code-card"><pre><code class="language-txt">Map(3)
0: {1 =&gt; "Jack"}
1: {2 =&gt; "Jill"}
2: {"animal" =&gt; "Elefante"}</code></pre><figcaption>Las entradas del objeto Map</figcaption></figure><p>Para recuperar un valor desde el objeto <code>Map</code>, necesitas usar el método <code>get()</code> y pasar la clave como su argumento.</p><figure class="kg-card kg-code-card"><pre><code class="language-js">console.log(myMap.get(1)); // Jack

console.log(myMap.get('animal')); // Elefante

</code></pre><figcaption>Recuperando valores del objeto Map</figcaption></figure><p>Para ver cuántos pares de clave/valor tiene un <code>Map</code>, puedes acceder a la propiedad <code>size</code>:</p><figure class="kg-card kg-code-card"><pre><code class="language-js">myMap.size; // 3</code></pre><figcaption>Accediendo a la propiedad Map.size</figcaption></figure><p>Para ver si una cierta clave existe en un objeto <code>Map</code>, puedes usar el método <code>has()</code>. Mira el ejemplo de abajo:</p><figure class="kg-card kg-code-card"><pre><code class="language-js">myMap.has(1); // true

myMap.has(10); // false</code></pre><figcaption>Usando el método Map.has()</figcaption></figure><p>Para quitar un par clave/valor de un objeto <code>Map</code>, puedes usar el método <code>delete()</code> y pasarle la clave de la par que quieres quitar de la siguiente forma:</p><figure class="kg-card kg-code-card"><pre><code class="language-js">myMap.delete(1);

console.log(myMap);
// 0: {2 =&gt; "Jill"}
// 1: {"animal" =&gt; "Elefante"}</code></pre><figcaption>Eliminando un entrada del objeto Map</figcaption></figure><p>Si quieres quitar todos los pares clave/valor, puedes usar el método <code>clear()</code>:</p><figure class="kg-card kg-code-card"><pre><code class="language-js">myMap.clear();

console.log(myMap); // Map(0) {size: 0}</code></pre><figcaption>Limpiando un objeto Map</figcaption></figure><!--kg-card-begin: html--><h3 id="otras-formas-crear-objeto-map">Otras formas de crear un Objeto Map</h3><!--kg-card-end: html--><p>También puedes crear un objeto <code>Map</code> desde un Arreglo de la siguiente manera:</p><figure class="kg-card kg-code-card"><pre><code class="language-js">const myMap = new Map([
  [1, 'Jack'],
  [2, 'Jill'],
  ['animal', 'Elefante'],
]);</code></pre><figcaption>Creando un Map desde un Arreglo</figcaption></figure><p>Cuando creas un <code>Map</code> desde un Arreglo, necesitas crear un arreglo de dos dimensiones y especificar dos elementos en cada arreglo.</p><p>El primer elemento será la clave, el segundo elemento será el valor. Cualquier otro valor extra en el arreglo será ignorado.</p><p>En el ejemplo de abajo, el valor "Johnson" del primer arreglo será ignorado por el constructor <code>Map()</code>:</p><figure class="kg-card kg-code-card"><pre><code class="language-js">const myMap = new Map([
  [1, 'Jack', 'Johnson'], // el valor 'Johnson' es ignorado
  [2, 'Jill'],
  ['animal', 'Elefante'],
]);</code></pre><figcaption>Creating a Map from an array with more than two values&nbsp;</figcaption></figure><p>Así como puedes crear un objeto <code>Map</code> desde un arreglo, también puedes crear uno desde un objeto. Necesitas transformar el objeto en un arreglo primero, usando el método <code>Object.entries()</code>.</p><p>El siguiente ejemplo muestra cómo usar un objeto para crear un <code>Map</code>:</p><figure class="kg-card kg-code-card"><pre><code class="language-js">const person = {
    'name': 'Jack',
    'age': 20,
}

const myMap = new Map(Object.entries(person));

console.log(myMap); // Map(2) { 'name' =&gt; 'Jack', 'age' =&gt; 20 }</code></pre><figcaption>Crear un Map desde un objeto</figcaption></figure><!--kg-card-begin: html--><h3 id="iterar-datos-objeto-map">Iterar sobre datos del objeto Map</h3><!--kg-card-end: html--><p>Para iterar sobre los datos de un objeto <code>Map</code>, puedes usar el método <code>forEach()</code> o el bucle <code>for..of</code>:</p><pre><code class="language-js">const myMap = new Map([
  [1, 'Jack'],
  [2, 'Jill'],
  ['animal', 'Elefante'],
]);

// iterar usando el método forEach()
myMap.forEach((value, key) =&gt; {
  console.log(`${key}: ${value}`);
});

// o usando el bucle for .. of 

for (const [key, value] of myMap) {
  console.log(`${key}: ${value}`);
}</code></pre><p>Ambos métodos proveen la misma salida:</p><pre><code class="language-txt">1: Jack
2: Jill
animal: Elefante</code></pre><!--kg-card-begin: html--><h3 id="cuando-usar-objeto-map">Cuándo usar el Objeto Map</h3><!--kg-card-end: html--><p>Puedes imaginarte a un objeto <code>Map</code> como un versión actualizada del Objeto regular. Puede usar cualquier tipo de dato como el valor clave, mientras que un objeto solamente puede usar los valores cadenas como claves.</p><p>Por debajo, el objeto <code>Map</code> se desempeña mejor cuando necesitas agregar y quitar claves, así que podrías considerar usarlo cuando tus datos cambia frecuentemente.</p><p>También, el objeto Map tiene muchos métodos útiles para manipulación de datos, tales como <code>has()</code> para ver si el Map contiene una clave específica, <code>keys()</code> para obtener todas las claves definidos en el <code>Map</code>, <code>values</code> para obtener todos los valores, y <code>entries()</code> para obtener todos los pares clave/valor.</p><p>Pero si solamente quieres crear un objeto sin manipulación adicional, entonces no necesitas usar el objeto <code>Map</code>.</p><p>Un ejemplo es cuando envías una solicitud de red usando el método <code>fetch()</code>. Crearías un objeto y lo convierte a una cadena JSON, así que usando un objeto <code>Map</code> no te dará ningún beneficio.</p><!--kg-card-begin: html--><h2 id="objeto-set-explicado">El Objeto Set explicado</h2><!--kg-card-end: html--><p>El objeto <code>Set</code> te permite almacenar una colección de elementos, así como un Arreglo. Las diferencias entre un <code>Set</code> y un arreglo son:</p><ul><li>Un <code>Set</code> requieres que todos los elementos sean únicos</li><li>Un <code>Set</code> tiene pocos métodos para manipulación de datos</li></ul><!--kg-card-begin: html--><h3 id="como-crear-objeto-set">Cómo crear un Objeto Set</h3><!--kg-card-end: html--><p>Para crear un nuevo objeto <code>Set</code>, necesitas llamar al constructor <code>Set()</code> de la siguiente manera:</p><figure class="kg-card kg-code-card"><pre><code class="language-js">const mySet = new Set();</code></pre><figcaption>Creando un nuevo objeto Set</figcaption></figure><p>El código de arriba creará un nuevo set vacío.</p><!--kg-card-begin: html--><h3 id="metodos-propiedades-objeto-set">Métodos y Propiedades del Objeto Set</h3><!--kg-card-end: html--><p>Un objeto <code>Set</code> tiene los siguientes métodos y propiedades:</p><ul><li><code>add(value)</code> – Agrega un valor a un Set</li><li><code>has(value)</code> – Verifica si un Set contiene una valor específico</li><li><code>delete(value)</code> – Quita un valor específico desde un Set</li><li><code>clear()</code> – Quita todos los elementos de un Set</li><li><code>keys()</code> – Devuelve todos las claves en un Set</li><li><code>values()</code> – Devuelve todos los valores en un Set</li><li><code>entries()</code> – Devuelve todos los valores en un Set como un arreglo <code>[key, value]</code></li><li><code>size</code> – Devuelve el número de elementos en un Set</li></ul><p>Fíjate que los métodos <code>keys()</code> y <code>values()</code> en un objeto Set regresa la misma salida.</p><p>También está el método <code>entries()</code> que regresa un arreglo de la siguiente forma:</p><figure class="kg-card kg-code-card"><pre><code class="language-js">const mySet = new Set(['Jack', 'Jill', 'John']);

console.log(mySet.entries());</code></pre><figcaption>Ejecutando el método entries() de Set</figcaption></figure><p>Salida:</p><figure class="kg-card kg-code-card"><pre><code class="language-txt">[Set Entries] {
  [ 'Jack', 'Jack' ],
  [ 'Jill', 'Jill' ],
  [ 'John', 'John' ]
}</code></pre><figcaption>Salida del método entries() de Set</figcaption></figure><p>Fíjate cómo los valores están repetidos una vez que cada arreglo de arriba. El método <code>entries()</code> es creado para hacer que <code>Set</code> similar al objeto <code>Map</code>, pero probablemente no lo necesites.</p><p>Hay métodos extras que puedes usar para interactuar con otro objeto <code>Set</code>. Los discutiremos en la próxima sección.</p><p>Para agregar un elemento al objeto Set, puedes usar el método agregar:</p><figure class="kg-card kg-code-card"><pre><code class="language-js">const mySet = new Set();

mySet.add(1);
mySet.add(2);
mySet.add(3);

console.log(mySet); // [1, 2, 3]</code></pre><figcaption>Agregando nuevos elementos al objeto Set</figcaption></figure><p>Para obtener todos los valores almacenados en un <code>Set</code>, llama al método <code>values()</code>:</p><figure class="kg-card kg-code-card"><pre><code class="language-js">mySet.values(); // [Set Iterator] { 'Jack', 'Jill', 'John' }</code></pre><figcaption>Obtener todos los valores de un objeto Set</figcaption></figure><p>Para verificar si el <code>Set</code> tiene un valor específico, usa el método <code>has()</code>:</p><figure class="kg-card kg-code-card"><pre><code class="language-js">mySet.has('Jack'); // true

mySet.has('Michael'); // false</code></pre><figcaption>Verifica si un Set tiene un valor específico</figcaption></figure><p>Para quitar un valor único, llama al método <code>delete()</code>. Para quitar todos los valores, usa el método <code>clear()</code>:</p><figure class="kg-card kg-code-card"><pre><code class="language-js">mySet.delete('Jill');

mySet.clear();</code></pre><figcaption>Elimina un valor único o limpia todo un Set</figcaption></figure><!--kg-card-begin: html--><h3 id="metodos-composicion-set">Métodos de Composición de Set</h3><!--kg-card-end: html--><p>Aparte de los métodos regulares de arriba, <code>Set</code> también tiene métodos de composición que puedes usar para realizar varias operaciones de teoría de set tales como diferencia, unión, e intersección.</p><p>La siguiente tabla es desde la <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set#set_composition">documentación de Set de MDN</a> (la tabla disponible sólo en inglés):</p><figure class="kg-card kg-image-card kg-width-wide kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2024/02/set-composition-methods.png" class="kg-image" alt="set-composition-methods" width="600" height="400" loading="lazy"><figcaption>Una lista de Métodos de Composición de Set</figcaption></figure><p>Por ejemplo, puedes obtener un conjunto que contiene las diferencias entre otros dos conjuntos de la siguiente forma:</p><figure class="kg-card kg-code-card"><pre><code class="language-js">const setA = new Set([1, 2, 3, 4, 5]);

const setB = new Set([4, 5, 6, 7, 8]);

const diffsA = setA.difference(setB); // Set(3) {1, 2, 3}
const diffsB = setB.difference(setA); // Set(3) {6, 7, 8}
</code></pre><figcaption>Ejemplo de usar el método difference() de Set</figcaption></figure><p>Aquí, el <code>setA.difference(setB)</code> regresa un <code>Set</code> que contiene valores únicos al objeto <code>setA</code>.</p><p>Los valores opuestos son devueltos cuando ejecutas el método <code>setB.difference(setA)</code>.</p><p>Fíjate que estos métodos son nuevas adiciones al estándar de JavaScript, y al momento de escribir este artículo, solamente Safari 17 y Chrome 122 soporta estos métodos.</p><blockquote><strong>Actualización</strong>: los <a href="https://web.dev/blog/set-methods?hl=en">nuevos métodos agregados al Objeto Set</a> están disponibles en todos los navegadores principales desde el 11 de Junio del año 2024.</blockquote><p>Más probable, estos métodos serán incluidos en Node.js pronto.</p><!--kg-card-begin: html--><h3 id="iterar-objeto-set">Iterar sobre un Objeto Set</h3><!--kg-card-end: html--><p>Para iterar sobre un objeto <code>Set</code>, puedes usar el método <code>forEach()</code> o el bucle <code>for..of</code>:</p><pre><code class="language-js">const mySet = new Set(['Jack', 'Jill', 'John']);

// iterar usando el método forEach()
mySet.forEach(value =&gt; {
  console.log(value);
});

// o usando el bucle for .. of

for (const value of mySet) {
  console.log(value);
}</code></pre><p>Salida:</p><pre><code class="language-txt">Jack
Jill
John</code></pre><!--kg-card-begin: html--><h3 id="cuando-usar-objeto-set">Cuándo usar el Objeto Set</h3><!--kg-card-end: html--><p>Puedes imaginarte del objeto <code>Set</code> como la versión alternativa del Arreglo regular.</p><p>Como un objeto <code>Set</code> ignora valores duplicados, puedes usar este objeto para eliminar duplicados de un Arreglo, luego vuelves a convertir un objeto <code>Set</code> devuelta a un Arreglo:</p><figure class="kg-card kg-code-card"><pre><code class="language-js">const myArray = [1, 1, 2, 2, 3, 3];

const uniqueArray = [...new Set(myArray)];

console.log(uniqueArray); // [ 1, 2, 3 ]</code></pre><figcaption>Creando un arreglo único con la ayuda de Set</figcaption></figure><p>Otra razón por que la que quisieras usar un <code>Set</code> es cuando necesites componer múltiples conjuntos de objetos usando los métodos de composición, tales como <code>union()</code> y <code>difference()</code>. Estos métodos no están disponibles en un Arreglo.</p><!--kg-card-begin: html--><h3 id="conclusion">Conclusión</h3><!--kg-card-end: html--><p>En este artículo, has aprendido cómo funcionan los objetos Map y Set y cuándo usarlos en tu código.</p><p>Si disfrutaste este artículo y quieres tomar tus habilidades de JavaScript al siguiente nivel, te recomiendo que mires mi nuevo libro <em><em><em><em><em><em><em><em>Beginning Modern JavaScript</em></em></em></em> </em></em></em></em><a href="https://codewithnathan.com/beginning-modern-javascript">aquí</a>.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2024/01/beginning-js-cover.png" class="kg-image" alt="beginning-js-cover" width="600" height="400" loading="lazy"></figure><p>El libro está diseñado para que sea fácil para los principiantes y accesible para cualquier que busca aprender JavaScript. Provee una guía amena de paso a paso que te ayudará a entender cómo usar JavaScript para crear una aplicación web dinámica.</p><p>Esta es mi promesa: <em>Realmente sentirás que comprendes lo que estás haciendo con JavaScript</em>.</p><p>¡Nos vemos luego!</p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Cómo hacer un menú desplegable con JavaScript ]]>
                </title>
                <description>
                    <![CDATA[ Si usas internet, es probable que ya hayas te hayas cruzado con un menú desplegable. Los menús desplegables tienen dos usos: recolectar la información ingresada por el usuario en los formularios web e implementar menús de acciones o navegación en aplicaciones web. Los menús desplegables son una de las mejores ]]>
                </description>
                <link>https://www.freecodecamp.org/espanol/news/como-hacer-un-menu-desplegable/</link>
                <guid isPermaLink="false">66913863b99552046f705ccc</guid>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Constanza Areal ]]>
                </dc:creator>
                <pubDate>Mon, 29 Jul 2024 21:03:50 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/espanol/news/content/images/2024/07/how-to-build-a-dropdown-menu-with-javascript.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artículo original:</strong> <a href="https://www.freecodecamp.org/news/how-to-build-a-dropdown-menu-with-javascript/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">How to Build a Dropdown Menu with JavaScript</a>
      </p><p>Si usas internet, es probable que ya hayas te hayas cruzado con un menú desplegable. Los menús desplegables tienen dos usos: recolectar la información ingresada por el usuario en los formularios web e implementar menús de acciones o navegación en aplicaciones web.</p><p>Los menús desplegables son una de las mejores maneras de ofrecer distintas opciones dentro de una colección de elementos sin comprometer el flujo de una aplicación. Además de aplicaciones web, también se los utiliza en software, sistemas operativos, etc.</p><p>En esta guía, vamos a aprender a hacer un menu desplegable de navegación usando HTML, CSS y JavaScript.</p><p>Al final de esta guía, voy a incluir el archivo de codepen para que puedas jugar con él.</p><figure class="kg-card kg-image-card kg-width-wide kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2022/12/dropdown-menu-with-css.png" class="kg-image" alt="dropdown-menu-with-css" width="600" height="400" loading="lazy"><figcaption>Resultado final del menú desplegable</figcaption></figure><p>Habiendo cubierto lo fundamental de los menús desplegables, vayamos paso por paso para hacer uno.</p><h2 id="paso-1-agregar-el-markup-para-el-menu-desplegable-"><strong>Paso 1: Agregar el markup para el menu desplegable.</strong></h2><p>Dado que vamos a usar iconos en esta guía, lo primero que debemos hacer es importarlos. Para hacerlo más simple, vamos a usar la librería gratuita, <a href="https://boxicons.com/">Boxicons</a>. Siéntete libre de elegir el ícono que prefieras.</p><p>Si bien hay distintas maneras de instalar Boxicons dentro de nuestro sitio, la manera más simple es la de fijar el script dentro de la etiqueta &nbsp;<code>head</code> de nuestro archivo HTML de este modo:</p><pre><code class="language-html">&lt;head&gt;
   &lt;link 
     href="https://unpkg.com/boxicons@2.1.4/css/boxicons.min.css" 
     rel="stylesheet"
    /&gt;
 &lt;/head&gt;</code></pre><p>Una vez que importamos los íconos, creamos un elemento <code>div</code> con la clase <code>container</code>. Este elemento contendrá otro elemento llamado <code>button</code> y el menú desplegable. </p><p>Dentro de este contenedor, creamos el elemento <code>button</code> y le damos la clase y el id <code>btn</code>. &nbsp;Al botón le vamos a agregar el texto y el ícono de una flecha.</p><p>Este es el código para el botón:</p><pre><code class="language-html">&lt;button class="btn" id="btn"&gt;
  Dropdown
  &lt;i class="bx bx-chevron-down" id="arrow"&gt;&lt;/i&gt;
&lt;/button&gt;</code></pre><p>Luego, vamos a agregar el código del menú desplegable propiamente dicho. Debajo de la etiqueta<code>button</code>, vamos a crear un elemento <code>div</code> con la clase y el id <code>dropdown</code>. Dentro del elemento div, creamos una etiqueta <code>a</code> para cada elemento del menú, con su texto e ícono respectivo.</p><p>Así es cómo debería verse el código:</p><pre><code class="language-html">&lt;div class="dropdown" id="dropdown"&gt;
  &lt;a href="#create"&gt;
    &lt;i class="bx bx-plus-circle"&gt;&lt;/i&gt;
    Create New
  &lt;/a&gt;
  &lt;a href="#draft"&gt;
    &lt;i class="bx bx-book"&gt;&lt;/i&gt;
    All Drafts
  &lt;/a&gt;
  &lt;a href="#move"&gt;
    &lt;i class="bx bx-folder"&gt;&lt;/i&gt;
    Move To
  &lt;/a&gt;
  &lt;a href="#profile"&gt;
    &lt;i class="bx bx-user"&gt;&lt;/i&gt;
    Profile Settings
  &lt;/a&gt;
  &lt;a href="#notification"&gt;
    &lt;i class="bx bx-bell"&gt;&lt;/i&gt;
    Notification
  &lt;/a&gt;
  &lt;a href="#settings"&gt;
    &lt;i class="bx bx-cog"&gt;&lt;/i&gt;
    Settings
  &lt;/a&gt;
&lt;/div&gt;</code></pre><p>Y este es el resultado:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2022/12/dropdown-menu-markup.png" class="kg-image" alt="dropdown-menu-markup" width="600" height="400" loading="lazy"><figcaption>Resultado del código del menú desplegable</figcaption></figure><p>Todavía no luce bien, así que vamos a darle estilos al menú.</p><h2 id="paso-2-d-ndole-estilos-al-men-desplegable"><strong>Paso 2: Dándole estilos al menú desplegable</strong></h2><p>Primero vamos a resetear los márgenes y el padding de cada elemento de la página y guardar alguno de los valores en variables reusables para poder utilizarlos en nuestro archivo CSS. Luego, le daremos al elemento body un estilo global.</p><pre><code class="language-css">@import url(https://fonts.googleapis.com/css?family=Inter:100,200,300,regular,500,600,700,800,900);

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
  font-family: "Inter", sans-serif;
  --shadow: rgba(0, 0, 0, 0.05) 0px 6px 10px 0px,
    rgba(0, 0, 0, 0.1) 0px 0px 0px 1px;
  --color: #166e67;
  --gap: 0.5rem;
  --radius: 5px;
}

body {
  margin: 2rem;
  background-color: #b3e6f4;
  font-size: 0.9rem;
  color: black;
}</code></pre><p>El próximo paso es darle estilo al botón y al contenedor del menú desplegable. Para agilizar las cosas, solo voy a explicar lo más importante sobre cómo dar estilo.<br><br>Copia este código y pégalo en tu archivo CSS:</p><pre><code class="language-css">.btn {
  background-color: white;
  display: flex;
  align-items: center;
  justify-content: flex-start;
  column-gap: var(--gap);
  padding: 0.6rem;
  cursor: pointer;
  border-radius: var(--radius);
  border: none;
  box-shadow: var(--shadow);
  position: relative;
}

.bx {
  font-size: 1.1rem;
}

.dropdown {
  position: absolute;
  width: 250px;
  box-shadow: var(--shadow);
  border-radius: var(--radius);
  margin-top: 0.3rem;
  background: white;
}

.dropdown a {
  display: flex;
  align-items: center;
  column-gap: var(--gap);
  padding: 0.8rem 1rem;
  text-decoration: none;
  color: black;
}

.dropdown a:hover {
  background-color: var(--color);
  color: white;
}</code></pre><p>Dado que los menús desplegables suelen ubicarse por sobre los elementos, el botón tiene posición relative y el menú desplegable, absolute. Esto permite que ambos elementos estén cerca uno del otro y que el menú desplegable se ubicará por arriba de otros elementos. De esta manera, al desplegarlo, no afectará el flujo de la página.</p><p>Este es el resultado:</p><figure class="kg-card kg-image-card kg-width-wide kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2022/11/dropdown-menu-with-css.png" class="kg-image" alt="dropdown-menu-with-css" width="600" height="400" loading="lazy"><figcaption>Dropdown menu styling&nbsp;</figcaption></figure><p>Ahora que ya le dimos estilo al menú desplegable, queremos que solo aparezca al apretar un botón en vez de hacerlo cuando pasamos con el puntero sobre él. </p><p>En un artículo anterior que escribí sobre <a href="https://freecodecamp.org/news/how-to-build-a-modal-with-javascript">cómo hacer un modal con JavaScript</a> [en inglés], usé <code>display: none</code> para inicialmente ocultar el elemento modal de la pantalla. Pero lo malo de utilizar esta propiedad es que, de acuerdo con <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_animated_properties">MDN Docs</a> [en inglés], la propiedad no es animable.</p><p>Por esto, en esta guía usaremos una manera distinta para ocultar el menú desplegable. Esto lo haremos combinando las propiedades <code>visibility</code> y <code>opacity</code>. Esta es la manera que <a href="https://github.com/">GitHub</a> utiliza para ocultar sus menús desplegables.</p><figure class="kg-card kg-image-card kg-width-wide kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2022/11/github-dropdown-menu.png" class="kg-image" alt="github-dropdown-menu" width="600" height="400" loading="lazy"><figcaption>Menú desplegable en GitHub</figcaption></figure><p>Dentro de la clase <code>dropdown</code> que creamos anteriormente, agregamos la propiedad <code>visibility </code> con el valor hidden y la opacidad establecida en 0. Al hacer esto, el menú desplegable aparecerá escondido al cargar la página.</p><p>Para mostrar el modal, &nbsp;vamos a crear una clase separada llamada <code>show</code>. Esta clase va a tener la propiedad <code>visibility </code> con el valor visible y una opacidad de 1. A esta clase la vamos a insertar usando JavaScript.</p><p>Este es el código:</p><pre><code class="language-css">.dropdown {
  position: absolute;
  width: 250px;
  box-shadow: var(--shadow);
  border-radius: var(--radius);
  margin-top: 0.3rem;
  background: white;
  transition: all 0.1s cubic-bezier(0.16, 1, 0.5, 1);
    
  transform: translateY(0.5rem);
  visibility: hidden;
  opacity: 0;
}

.show {
  transform: translateY(0rem);
  visibility: visible;
  opacity: 1;
}

.arrow {
  transform: rotate(180deg);
  transition: 0.2s ease;
}</code></pre><p>Sumado al código para ocultar el elemento modal, añadimos otra clase para rotar el icono de flecha cuando se aprieta el botón del menú.</p><h2 id="paso-3-agregando-funcionalidad-al-men-desplegable"><strong>Paso 3: Agregando funcionalidad al menú desplegable</strong></h2><p>Primero, vamos a guardar los distintos elementos en variables para poder reutilizarlos.</p><pre><code class="language-js">const dropdownBtn = document.getElementById("btn");
const dropdownMenu = document.getElementById("dropdown");
const toggleArrow = document.getElementById("arrow");</code></pre><p>El próximo paso es crear una función para insertar la clase <code>show</code> del elemento desplegable y rotar la flecha del menú al apretar el botón. A esta función la llamaremos <code>toggleDropdown</code>. </p><pre><code class="language-js">const toggleDropdown = function () {
  dropdownMenu.classList.toggle("show");
  toggleArrow.classList.toggle("arrow");
};</code></pre><p>Luego vamos a agregar esta función en el botón del menú desplegable con el método <code>addEventListener</code> para que cada vez que el botón se apriete, active la función que controla que el menú desplegable se oculte o despliegue. </p><pre><code class="language-js">dropdownBtn.addEventListener("click", function (e) {
  e.stopPropagation();
  toggleDropdown();
});</code></pre><p>Si no te diste cuenta, añadimos ell método <code>stopPropagation()</code>dentro de la función del menú desplegable. Esto hace que la función del elemento botón no la herede el elemento padre y se ejecute dos veces. Esto lo entenderás más en la próxima sección.</p><p>Este es el resultado:</p><figure class="kg-card kg-image-card kg-width-wide kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2022/11/toggle-dropdown-menu-.gif" class="kg-image" alt="toggle-dropdown-menu-" width="600" height="400" loading="lazy"><figcaption>Despliegue del menú</figcaption></figure><h2 id="c-mo-cerrar-un-men-desplegable-cuando-un-elemento-del-dom-se-aprieta"><strong>Cómo cerrar un menú desplegable cuando un elemento del DOM se aprieta</strong></h2><p>Es posible cerrar un menú desplegable de cuatro formas distintas:</p><ul><li>Al apretar el botón que lo activa</li><li>Al hacer clic sobre cualquiera de sus elementos individuales</li><li>Al hacer clic fuera del menú (en el body de la página)</li><li>Al apretar el botón Escape o el botón de flecha hacia abajo del teclado.</li></ul><p>Pero en esta guía nos vamos a concentrar en los primeros tres.</p><p>Primero, vamos a seleccionar el elemento raíz <code>&lt;html&gt;</code> con <code>document.documentElement</code>. Y como hicimos anteriormente, vamos a insertar la función <code>toggleDropdown()</code> dentro de él.</p><p>Pero esta vez queremos poner una condición que chequee si el menú desplegable contiene o no la clase <code>show</code>. Solo cuando la tenga vamos a querer que se active la función para ocultar el menú.</p><pre><code class="language-js">document.documentElement.addEventListener("click", function () {
  if (dropdownMenu.classList.contains("show")) {
    toggleDropdown();
  }
});</code></pre><p>Este es el resultado final:</p><figure class="kg-card kg-image-card kg-width-wide kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2022/12/close-dropdown-when-dom-element-is-clicked.gif" class="kg-image" alt="close-dropdown-when-dom-element-is-clicked" width="600" height="400" loading="lazy"><figcaption>Menú desplegable cerrado cuando se hace clic sobre un elemento del DOM</figcaption></figure><p>Y así es como se hace un menú desplegable con JavaScript. Abajo está el archivo de codepen para ver el menú desplegable en acción.</p><figure class="kg-card kg-embed-card"><iframe height="400" scrolling="no" title="Dropdown menu" src="https://codepen.io/evavic44/embed/eYKQJjJ?default-tab=html%2Cresult&amp;theme-id=light" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true" style="box-sizing: inherit; margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 22px; vertical-align: middle; width: 720px;"></iframe></figure><h2 id="conclusi-n"><strong>Conclusión</strong></h2><p>Espero, de corazón, que este post te haya resultado útil o interesante. Si fue así, te pido que lo compartas con tus amigos o suscríbete a mi blog así no te pierdes ningún post. Gracias por leer.</p><p><a href="https://github.com/evavic44">GitHub</a> | <a href="https://twitter.com/victorekea">Twitter</a> | <a href="https://eke.hashnode.dev/">Blog</a> | <a href="https://victoreke.com/">Portfolio</a></p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Practica HTML, CSS y JavaScript creando 3 proyectos ]]>
                </title>
                <description>
                    <![CDATA[ Crear proyectos es muy importante para aprender a programar. Cuando construyes un proyecto, amplías tu portafolio y aprendes a aplicar tus conocimientos a nuevos escenarios. Acabamos de publicar un curso de 2 horas en el canal de YouTube en español de freeCodeCamp.org [https://www.youtube.com/freecodecampespanol] que te guiará paso a paso en ]]>
                </description>
                <link>https://www.freecodecamp.org/espanol/news/practica-html-css-javascript-creando-3-proyectos/</link>
                <guid isPermaLink="false">669426ecb99552046f705e4f</guid>
                
                    <category>
                        <![CDATA[ HTML ]]>
                    </category>
                
                    <category>
                        <![CDATA[ CSS ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Estefania Cassingena Navone ]]>
                </dc:creator>
                <pubDate>Thu, 18 Jul 2024 04:00:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/espanol/news/content/images/2024/07/Proyectos-CSS-1-1.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Crear proyectos es muy importante para aprender a programar. Cuando construyes un proyecto, amplías tu portafolio y aprendes a aplicar tus conocimientos a nuevos escenarios.</p><p>Acabamos de publicar un curso de 2 horas en el <a href="https://www.youtube.com/freecodecampespanol">canal de YouTube en español de freeCodeCamp.org</a> que te guiará paso a paso en la creación de 3 proyectos con HTML, CSS y JavaScript. Practicarás tus habilidades creando una barra de navegación responsiva con menús desplegables, un carrusel (<em>slider)</em>, y una <em>landing page</em> con un modal personalizado.</p><p>Jordan Alexander Cruz García creó este curso. Jordan Alexander es desarrollador y le encanta compartir sus conocimientos y enseñar a otros sobre el asombroso mundo de CSS.</p><p><strong>💡 Dato: </strong>El curso se enfoca en HTML y CSS pero también requiere conocimientos básicos de JavaScript para implementar la interactividad.</p><h2 id="html-css-y-javascript"><strong>HTML, CSS y JavaScript</strong></h2><figure class="kg-card kg-image-card"><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1721081239678/cbb8391c-ddec-49fb-a806-75bb00fe5673.png" class="kg-image" alt="cbb8391c-ddec-49fb-a806-75bb00fe5673" width="2722" height="1052" loading="lazy"></figure><p>HTML significa <strong>HyperText Markup Language</strong> y CSS significa <strong><em>Cascading Style Sheet</em></strong> (hojas de estilo en cascada). Mientras que HTML proporciona la estructura y el contenido de un sitio web, CSS determina cómo se muestra el contenido. Controla los aspectos visuales del sitio web, como fuentes, colores, diseños, espacios y animaciones.</p><p>Con CSS, puedes crear fácilmente diferentes estilos y diseños para varios tamaños de pantalla y lograr que tu sitio web se vea genial en computadoras, tabletas y dispositivos móviles.</p><p><strong>💡 Dato:</strong> Los sitios web que se adaptan a distintos tamaños de pantalla se conocen como "sitios web responsivos".</p><p>Normalmente escribimos CSS en un archivo externo al que nos referimos como "hoja de estilo". Luego, enlazamos esta hoja de estilo al archivo HTML, lo cual aplica todos los estilos a los elementos HTML correspondientes en base a los selectores y propiedades CSS.</p><p>Separar el contenido del sitio web de su presentación es muy útil. Permite que nuestro proyecto tenga una estructura más fácil de mantener y un proceso de renderizado más eficiente porque los navegadores pueden renderizar la estructura más rápidamente, mientras descargan los estilos CSS en segundo plano.</p><p>Básicamente, CSS es una herramienta esencial para crear los sitios web hermosos, visuales y fáciles de usar que vemos hoy en día.</p><p>JavaScript agrega interactividad. Convierte los elementos sencillos en elementos interactivos para crear experiencias de usuario geniales.</p><h2 id="proyectos-de-html-css-y-javascript-en-espa-ol"><strong>Proyectos de HTML, CSS y JavaScript en español</strong></h2><p>Genial. Ahora que ya sabes más sobre HTML, CSS y JavaScript, veamos los proyectos que crearás durante el curso.</p><h3 id="proyecto-1-barra-de-navegaci-n"><strong>Proyecto 1: Barra de Navegación</strong></h3><p>Comenzarás el curso creando una barra de navegación con menús desplegables. Esta barra de navegación será responsiva, por lo que se expandirá o encogerá para adaptarse al tamaño de la pantalla. Si la pantalla es muy pequeña, se transformará automáticamente en una barra lateral.</p><p><strong>💡 Dato: </strong>Siempre se mostrarán las opciones principales. Cuando el usuario haga clic en "<em>About</em>" o "<em>Projects</em>", se mostrará un menú desplegable con opciones adicionales.</p><p><strong>Version de escritorio</strong></p><p>Aquí puedes ver la versión de escritorio.</p><figure class="kg-card kg-image-card"><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1720982288758/932e25d8-c6ad-4d0d-b54a-19e12aff07bc.png" class="kg-image" alt="932e25d8-c6ad-4d0d-b54a-19e12aff07bc" width="1104" height="561" loading="lazy"></figure><p><strong>Version móvil</strong></p><p>Esta es la versión móvil que verás en dispositivos pequeños.</p><p><strong>💡 Dato:</strong> Esta técnica de ocultar y alternar la barra de navegación se utiliza con mucha frecuencia para optimizar al máximo el espacio disponible para el contenido.</p><figure class="kg-card kg-image-card"><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1720982239484/6d4882b0-044f-40d7-9c15-220e25449826.png" class="kg-image" alt="6d4882b0-044f-40d7-9c15-220e25449826" width="623" height="800" loading="lazy"></figure><h3 id="proyecto-2-carrusel"><strong>Proyecto 2: Carrusel</strong></h3><p>Luego, crearás un carrusel (<em>slider</em>) con tres posiciones que cambiarán cuando el usuario haga clic en las flechas. Cada posición tendrá un título, un párrafo breve y una imagen circular.</p><p><strong>💡Dato: </strong>Los controles deslizantes son útiles para compartir comentarios, citas y reseñas de los usuarios.</p><figure class="kg-card kg-image-card"><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1720976794338/6eeac0de-8dca-4a8b-8568-9c4b44220808.png" class="kg-image" alt="6eeac0de-8dca-4a8b-8568-9c4b44220808" width="1915" height="986" loading="lazy"></figure><h3 id="proyecto-3-landing-page"><strong>Proyecto 3: Landing Page</strong></h3><p>Finalmente, crearás una <em>landing page</em> (página web principal) paso a paso con CSS Grid.</p><p>Cuando el usuario haga clic en "Join us", se mostrará una ventana modal personalizada. Implementarás este modal con HTML, CSS y JavaScript paso a paso.</p><figure class="kg-card kg-image-card"><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1720982884236/b5e066bc-7307-4078-bf45-d1cbe50f0b6d.png" class="kg-image" alt="b5e066bc-7307-4078-bf45-d1cbe50f0b6d" width="1913" height="938" loading="lazy"></figure><p>Te invitamos a ver el curso en el canal de YouTube de <a href="https://www.youtube.com/freecodecampespanol">freeCodeCamp.org en español</a>:</p><figure class="kg-card kg-embed-card" data-test-label="fitted">
        <div class="fluid-width-video-container">
          <div style="padding-top: 56.49999999999999%;" class="fluid-width-video-wrapper">
            <iframe width="200" height="113" src="https://www.youtube.com/embed/yZeXLvHP6LM?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" title="Crea 3 Proyectos con HTML, CSS y JavaScript - Curso Práctico" name="fitvid0"></iframe>
          </div>
        </div>
      </figure><p>✍️ Curso creado por Jordan Alexander Cruz Garcia.</p><ul><li>YouTube: <a href="https://www.youtube.com/c/AlexCGDesign" rel="noopener noreferrer nofollow">@AlexCGDesign</a></li><li>Twitter: <a href="https://x.com/alexcgdesign" rel="noopener noreferrer nofollow">@alexcgdesign</a></li><li>Linkedin: <a href="https://www.linkedin.com/in/jordan-alexander-cruz-garcia-07626115a/" rel="noopener noreferrer nofollow">Jordan Alexander Cruz Garcia</a></li><li>Instagram: <a href="https://www.instagram.com/alexcg_design/" rel="noopener noreferrer nofollow">@alexcg_design</a></li><li>GitHub: <a href="https://github.com/AlexCGDesign" rel="noopener noreferrer nofollow">AlexCGDesign</a></li><li>Web Development Blog: <a href="https://www.alexcgdesign.com/blog" rel="noopener noreferrer nofollow">https://www.alexcgdesign.com/blog</a></li></ul> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Cómo codificar y decodificar HTML Base64 usando JavaScript: Ejemplo de codificación en JS ]]>
                </title>
                <description>
                    <![CDATA[ Cuando construyes una aplicación o escribes un programa, podrías necesitar codificar o decodificar con HTML Base64 en JavaScript. Esto es posible gracias a las dos funciones auxiliares Base64 que son parte de la especificación de HTML y están soportados por todos los navegadores modernos. En este artículo, aprenderás sobre Base64 ]]>
                </description>
                <link>https://www.freecodecamp.org/espanol/news/como-codificar-y-decodificar-html-base64-usando-javascript-ejemplo-de-codificacion-en-js/</link>
                <guid isPermaLink="false">66853f33e96bc003fb5d3a3e</guid>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Elias Ezequiel Pereyra Gomez ]]>
                </dc:creator>
                <pubDate>Tue, 16 Jul 2024 13:39:58 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/espanol/news/content/images/2024/07/cover-template-1.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artículo original:</strong> <a href="https://www.freecodecamp.org/news/encode-decode-html-base64-using-javascript/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">How to Encode and Decode HTML Base64 using JavaScript – JS Encoding Example</a>
      </p><p>Cuando construyes una aplicación o escribes un programa, podrías necesitar codificar o decodificar con HTML Base64 en JavaScript.</p><p>Esto es posible gracias a las dos funciones auxiliares Base64 que son parte de la especificación de HTML y están soportados por todos los navegadores modernos.</p><p>En este artículo, aprenderás sobre Base64 y cómo funciona para convertir datos binarios, cadenas regulares, y un montón más sobre texto ASCII.</p><h2 id="-qu-es-base64"><strong>¿Qué es Base64?</strong></h2><p><a href="https://es.wikipedia.org/wiki/Base64">Base64</a> es un grupo de esquemas de codificación de binario a texto que representa los datos binarios en formato de cadena ASCII. Es usado comúnmente para codificar datos que necesitan ser almacenados o transmitidos de una forma que puede ser representado directamente como texto.</p><p>La <strong>codificación Base64</strong> funciona al mapear datos binarios a caracteres 64 desde el conjunto de caracteres ASCII. Los caracteres 64 usados en codificación Base64 son: <code>A-Z</code>, <code>a-z</code>, <code>0-9</code>, <code>+</code>, y <code>/</code>.</p><p>El proceso de codificación toma 3 bytes de datos binarios y los mapea a 4 caracteres desde el conjunto de arriba, de tal forma que un solo carácter representa cada 6 bits de datos binarios. El resultado es una cadena de caracteres ASCII que puede ser transmitido o almacenado como texto.</p><p>La <strong>decodificación Base64</strong> es el proceso inverso de codificación. Toma una cadena codificada en Base64 y mapea cada carácter a su representación binario de 6-bits. Los datos binarios resultantes es una reconstrucción de los datos binarios originales codificados a Base64.</p><h2 id="c-mo-codificar-y-decodificar-html-base64-usando-javascript"><strong>Cómo codificar y decodificar HTML Base64 usando JavaScript</strong></h2><p>Para codificar y decodificar en JavaScript, usarás las funciones <code>btoa()</code> y <code>atob()</code> de JavaScript que están disponibles y soportados por los navegadores web.</p><p>Estas funciones auxiliares de JavaScript llevan nombres de comandos viejos de Unix para convertir <em>binario</em> a <em>ASCII</em> (<strong>btoa</strong>) y <em>ASCII</em> a <em>binario</em> (<strong>atob</strong>).</p><p>Puedes codificar una cadena a base64 en JavaScript usando la función <code>btoa()</code> y decodificar una cadena base64 usando la función <code>atob()</code>. Por ejemplo, si tienes una cadena almacenada en una variable, como se ve abajo, puedes primero codificarlo a Base64:</p><pre><code class="language-js">let miCadena = "Bienvenido a freeCodeCamp!";
let valorCodificado = btoa(miCadena);
console.log(valorCodificado); // V2VsY29tZSB0byBmcmVlQ29kZUNhbXAh
</code></pre><p>También puedes decodificar el <code>valorCodificado</code> de vuelta a su forma original usando la función <code>atob()</code>. Esta función toma el valor codificado y lo decodifica desde Base64:</p><pre><code class="language-js">let miCadena = "Bienvenido a freeCodeCamp!";
let valorCodificado = btoa(miCadena);
let valorDecodificado = atob(valorCodificado);
console.log(valorDecodificado); // Bienvenido a freeCodeCamp!
</code></pre><p>Ahora sabes cómo codificar y decodificar Base64 en JavaScript.</p><h2 id="m-s-ejemplos-de-codificaci-n-en-javascript"><strong>Más ejemplos de Codificación en JavaScript</strong></h2><p>También puedes codificar datos binarios a texto ASCII codificado en Base64 en JavaScript usando la función <code>btoa()</code>:</p><pre><code class="language-js">let binaryData = new Uint8Array([72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100]);
let stringValue = String.fromCharCode.apply(null, binaryData);
console.log(stringValue); // "Hello World"

let encodedValue = btoa(stringValue);
console.log(encodedValue); // SGVsbG8gV29ybGQ=
</code></pre><p>Arriba, primero convertiste los valores <code>Unicode</code> a caracteres y luego codificaste la cadena.</p><p>También puedes decodificar el texto ASCII codificado en Base64 a datos binarios en JavaScript usando la función <code>atob()</code>:</p><pre><code class="language-js">let encodedValue = "SGVsbG8gV29ybGQ=";
let binaryData = new Uint8Array(atob(encodedValue).split("").map(function (c) {
    return c.charCodeAt(0);
}));
console.log(binaryData); // Uint8Array [72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100]
</code></pre><h2 id="-resumiendo-"><strong>¡Resumiendo!</strong></h2><p>En este artículo, has aprendido lo que significa Base64, cómo funciona, y cuándo codificar y decodificar en JavaScript.</p><p>Base64 no está destinado a ser el método de encriptación seguro, ni está destinado a ser un método de compresión, porque codificar una cadena a Base64 típicamente resulta en una salida 33% más larga.</p><p>La codificación Base64 es usado comúnmente en JavaScript para situaciones como:</p><ul><li>Almacenar y transmitir datos binarios como texto.</li><li>Encriptar datos donde los datos codificados se envían sobre un canal inseguro y decodificado en el otro fin. Sin embargo, no debería ser considerado como un método de encriptación seguro, ya que puede ser fácilmente decodificado.</li><li>La transferencia de datos entre sistemas con conjuntos de caracteres distintos.</li><li>Almacenar datos binarios en una base de datos.</li></ul><p>¡Gracias por leer y disfruta programando!</p><p>Puedes acceder cerca de 185 artículos míos <a href="https://joelolawanle.com/contents">visitando mi sitio web</a>. También puede usar el campo de búsqueda para ver si he escrito un artículo específico.</p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Cómo extraer un objeto de error de una respuesta de la API Blob en JavaScript ]]>
                </title>
                <description>
                    <![CDATA[ Encontré un problema cuando realicé una solicitud GET en mi proyecto de React que se suponía que devolvería un archivo que podía descargar. Para que el archivo se descargara correctamente, tuve que hacer que la respuesta fuera un  blob [https://developer.mozilla.org/es/docs/Web/API/Blob]. Pero si ocurriera un error cuando el servidor devuelve ]]>
                </description>
                <link>https://www.freecodecamp.org/espanol/news/como-extraer-un-objeto-de-error-de-una-respuesta-de-blob-api-en-javascript/</link>
                <guid isPermaLink="false">668edaf1b99552046f705c08</guid>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Blob ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web API ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Cristian Fernando Villca Gutierrez ]]>
                </dc:creator>
                <pubDate>Mon, 15 Jul 2024 14:17:14 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/espanol/news/content/images/2024/07/React-form-validation--1--1.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artículo original:</strong> <a href="https://www.freecodecamp.org/news/how-to-extract-an-error-object-from-a-blob/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">How to Extract an Error Object from a Blob API Response in JavaScript</a>
      </p><p>Encontré un problema cuando realicé una solicitud GET en mi proyecto de React que se suponía que devolvería un archivo que podía descargar. Para que el archivo se descargara correctamente, tuve que hacer que la respuesta fuera un <a href="https://developer.mozilla.org/es/docs/Web/API/Blob">blob</a>.</p><p>Pero si ocurriera un error cuando el servidor devuelve un objeto JSON, no podría obtener ese objeto porque ya había definido el tipo de respuesta como un blob. Y si elimino la definición de blob, el archivo simplemente regresará como JSON normal y es posible que no se descargue correctamente.</p><p>Entonces, ¿cómo consigo que el blob lo descargue y recupere el objeto de error en caso de que algo no haya salido bien desde el servidor? Afortunadamente, hay una manera de lograrlo.</p><p>Esta guía te mostrará cómo conservar un objeto JSON para fines de manejo de errores y, al mismo tiempo, podrás descargar un archivo desde un servidor. Usaremos <a href="https://axios-http.com/">Axios</a>, una biblioteca de JavaScript utilizada para realizar solicitudes HTTP, para realizar nuestra llamada API.</p><h1 id="paso-1-definir-el-tipo-de-respuesta-en-la-llamada-api">Paso 1: Definir el tipo de respuesta en la llamada API</h1><p>Primero, define una función que realice la solicitud HTTP al servidor. En este caso, esperamos un archivo, por lo que el verbo HTTP convencional sería GET.</p><p>El tipo de respuesta para las solicitudes de Axios es JSON de forma predeterminada, pero queremos cambiarlo a un blob como este:</p><pre><code class="language-js">import axios from "axios";

const obtenerArchivoDelServidor = () =&gt; {
    const respuesta = await axios.get('https://api.some-server.com', {responseType: 'blob'})?.data;
    return respuesta;
}</code></pre><h1 id="paso-2-convertir-el-blob-a-texto">Paso 2: Convertir el Blob a Texto</h1><p>En el paso anterior, pudimos obtener nuestro archivo como un blob fácilmente. Pero cuando se trata de mostrar el error, necesitamos que se muestre como JSON.</p><p>Primero, necesitamos envolver la solicitud en una declaración <a href="https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Statements/try...catch">try/catch</a> para especificar qué debería suceder si se genera un error mientras se realiza la solicitud.</p><pre><code class="language-js">import axios from "axios";

const obtenerArchivoDelServidor = async () =&gt; {
    try {
        const respuesta = await axios.get('https://api.some-server.com', {responseType: 'blob'}).data;
    return respuesta;
    }
    catch (error) {
        let errorRespuesta = await error.response.data.text();
        const errorObjeto = JSON.parse(response);
        console.log(errorObjeto) // mostramos el error por consola
    }
}</code></pre><p>La conversión de tipo se realizó dentro del bloque <code>catch</code>. Primero, convertimos los datos de respuesta a una cadena JSON usando el método <code>text()</code> de la API Fetch de JavaScript.</p><p>Finalmente, utilizamos el método <code>JSON.parse()</code> para convertir esa cadena a JSON real. De esa manera, podemos acceder al objeto en el formato previsto y al mismo tiempo recuperar el archivo del servidor si no hay ningún error.</p><p>Mostrando el objeto de error en la consola dará como resultado algo como esto:</p><pre><code class="language-js">{
  "statusCode": 400,
  "message": "Algún error ocurrió"
}</code></pre><h1 id="conclusi-n">Conclusión</h1><p>Este es uno de los problemas que enfrenté en la vida real, así que pensé en compartirlo en caso de que alguien más lo encuentre. </p><p>Déjame saber tu opinión sobre el artículo y no dudes en hacer cualquier sugerencia que creas que podría mejorar mi solución. </p><p>¡Gracias por leer!</p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Cómo usar la API Geolocation API en JavaScript: con ejemplos de código ]]>
                </title>
                <description>
                    <![CDATA[ La API Geolocation es una API estándar implementada en navegadores para recuperar la ubicación de las personas quienes están interactuando con una aplicación web. Esta API permite a los usuarios que envíen su ubicación a una aplicación web para permitir servicios relevantes, tales como buscar un restaurante o un hotel ]]>
                </description>
                <link>https://www.freecodecamp.org/espanol/news/como-usar-la-api-geolocation-api-en-javascript-con-ejemplos-de-codigo/</link>
                <guid isPermaLink="false">66834975e96bc003fb5d3904</guid>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web API ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Geolocation API ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Elias Ezequiel Pereyra Gomez ]]>
                </dc:creator>
                <pubDate>Mon, 08 Jul 2024 18:37:44 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/espanol/news/content/images/2024/07/js-geolocation-api-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/how-to-use-the-javascript-geolocation-api/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">How to Use the Geolocation API in JavaScript – with Code Examples</a>
      </p><p>La API Geolocation es una API estándar implementada en navegadores para recuperar la ubicación de las personas quienes están interactuando con una aplicación web.</p><p>Esta API permite a los usuarios que envíen su ubicación a una aplicación web para permitir servicios relevantes, tales como buscar un restaurante o un hotel cercano al usuario.</p><p>En este artículo, voy a mostrarte cómo se usa la API Geolocation con JavaScript y mostrar la ubicación actual del usuario usando una API de un mapa.</p><p>¡Comencemos!</p><h2 id="c-mo-acceder-a-la-api-geolocation"><strong>Cómo acceder a la API Geolocation</strong></h2><p>Los Navegadores implementan la API Geolocation en el objeto <code>navigator.geolocation</code>. Puedes verificar si el navegador que usas soporta esta API de esta forma:</p><pre><code class="language-js">if ('geolocation' in navigator) {
  console.log('Geolocation está disponible');
} else {
  console.log('Geolocation NO está disponible');
}
</code></pre><p>Si el navegador responde con 'Geolocation está disponible', entonces puedes usar los métodos del objeto <code>geolocation</code> para obtener los datos del usuario.</p><p>La API Geolocation solamente está disponible bajo un contexto de HTTPS seguro, pero los navegadores modernos como Chrome y Firefox permiten el acceso a esta API desde localhost para propósitos de desarrollo.</p><p>Hay dos métodos que puedes usar para obtener datos de usuario:</p><ul><li><code>getCurrentPosition()</code>: Regresa la posición actual del dispositivo.</li><li><code>watchPosition()</code>: Observa la posición del dispositivo continuamente hasta que el observador se detiene.</li></ul><p>Ambos métodos de arriba reciben 3 argumentos de esta forma:</p><ul><li><code>success</code>: una función callback para cuando se recuperan los datos de geolocalización (requerido).</li><li><code>error</code>: una función callback para cuando el método encuentra un error (opcional).</li><li><code>options</code>: un objeto definiendo parámetros extras cuando se ejecuta el método (opcional).</li></ul><p>Cuando a la API Geolocation se accede por primera vez, una solicitud de permiso aparecerá cerca de la barra de URL como se muestra abajo:</p><figure class="kg-card kg-image-card kg-width-wide kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2024/02/geolocation-permission.png" class="kg-image" alt="geolocation-permission" width="600" height="400" loading="lazy"><figcaption>Solicitando permiso para acceder a la Ubicación del Usuario</figcaption></figure><p>Podrías estar familiarizado con la ventanita emergente de arriba. Cuando eliges bloquear la solicitud, entonces la función callback <code>error</code> se ejecutará por la API.</p><p>De otra forma, el callback <code>success</code> será ejecutado.</p><h2 id="c-mo-obtener-la-posici-n-actual-del-usuario"><strong>Cómo obtener la posición actual del Usuario</strong></h2><p>Para obtener la posición actual del usuario, puedes llamar a la función <code>getCurrentPosition()</code> desde el objeto, <code>navigator.geolocation</code> como se muestra abajo:</p><pre><code class="language-js">function success(position) {
  console.log(position);
}

navigator.geolocation.getCurrentPosition(success);
</code></pre><p>El método <code>getCurrentPosition()</code> enviará el objeto <code>position</code> a la función <code>success()</code> de arriba.</p><p>El objeto <code>position</code> contiene las coordenadas de ubicación y las marcas de tiempo mostrando cuando se recuperó la ubicación. </p><p>Lo de abajo es un ejemplo del objeto <code>position</code>:</p><pre><code class="language-js">{
  coords: {
    latitude: 1.314,
    longitude: 103.84425
    altitude: null
  },
  timestamp: 1708674456885
}
</code></pre><p>Usando la información de latitud y longitud, puedes determinar con precisión la ubicación del usuario y proveer información y servicios relevantes.</p><p>Por ejemplo, veamos cómo puedes enviar una solicitud al sitio web <a href="https://www.openstreetmap.org/">OpenStreetMap</a> y determinar la ubicación actual del usuario usando los datos desde la API Geolocation.</p><p>OpenStreetMap es un proyecto de código abierto que provee un mapa geográfico gratuito de todo el planeta.</p><p>Necesitas crear un documento HTML con el siguiente contenido body:</p><pre><code class="language-html">&lt;body&gt;
  &lt;button id="getLocation"&gt;Obtener ubicación&lt;/button&gt;
  &lt;br&gt;
  &lt;a id="locationResult" target="_blank"&gt;&lt;/a&gt;
&lt;/body&gt;
</code></pre><p>Cuando el usuario hace clic en el botón <em>Obtener ubicación</em> de arriba, accederemos a la API Geolocation, recuperando la ubicación del usuario, y proveer un enlace para ver la ubicación del usuario en un mapa.</p><p>Luego, crea una etiqueta <code>&lt;script&gt;</code> antes de cerrar la etiqueta <code>&lt;/body&gt;</code> y escribe el siguiente código de JavaScript:</p><pre><code class="language-html">&lt;script&gt;
  const locationResult = document.querySelector('#locationResult');
  document.querySelector('#getLocation').addEventListener('click', () =&gt; {
    locationResult.textContent = 'Recuperando la Ubicacion del Usuario...'

    function success(position) {
      let { coords } = position;
      locationResult.textContent = 'Vea mi ubicacion en un mapa';
      locationResult.href = `https://www.openstreetmap.org?mlat=${coords.latitude}&amp;mlon=${coords.longitude}`;
    }

    navigator.geolocation.getCurrentPosition(success);
  });
&lt;/script&gt;
</code></pre><p>Cuando se hace clic al botón, ejecutaremos el método <code>getCurrentPosition()</code> y definimos el atributo <code>href</code> de la etiqueta <code>&lt;a&gt;</code> al sitio web OpenStreetMap, pasándole los datos <code>latitude</code> y <code>longitude</code> bajo la cadena de solicitud <code>mlat</code> y <code>mlong</code>.</p><p>Visitando el enlace, mostraría un mapa de la ubicación actual como se muestra abajo:</p><figure class="kg-card kg-image-card kg-width-wide kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2024/02/geolocation-getCurrentPosition.png" class="kg-image" alt="OpenStreetMap Using Geolocation API data" width="600" height="400" loading="lazy"><figcaption>El Sitio web OpenStreetMap determina los datos Latitud y Longitud</figcaption></figure><p>Y así es cómo obtienes la ubicación actual del usuario. Cómo procesar la información de ubicación depende de ti.</p><p>He creado un sitio web donde puedes probar esta funcionalidad en <a href="https://nathansebhastian.github.io/js-geolocation-api/">https://nathansebhastian.github.io/js-geolocation-api/</a>.</p><p>Ahora, aprendamos sobre el método <code>watchPosition()</code>.</p><h2 id="c-mo-observar-la-posici-n-del-usuario"><strong>Cómo observar la Posición del Usuario</strong></h2><p>El método <code>watchPosition()</code> continuará observando la posición del dispositivo cuando se llama. Ejecutará la función callback <code>success</code> cada vez que la ubicación del dispositivo cambie.</p><p>Puedes llamar al método como sigue:</p><pre><code class="language-js">function success(position) {
  const { coords } = position;
  console.log('Latitude data: ' + coords.latitude);
  console.log('Longitude data: ' + coords.longitude);
}

navigator.geolocation.watchPosition(success);
</code></pre><p>El método <code>watchPosition()</code> regresa un número ID que rastrea al observador. Si quieres hacer que el observador deje de enviar datos de ubicación, necesitas llamar al método <code>clearWatch()</code> y pasar el número ID:</p><pre><code class="language-js">function success(position) {
  const { coords } = position;
  console.log('Latitude data: ' + coords.latitude);
  console.log('Longitude data: ' + coords.longitude);
}

// Almacena el numero ID en una variable
const watcherID = navigator.geolocation.watchPosition(success);

// Detiene al observador
navigator.geolocation.clearWatch(watcherID);
</code></pre><p>Y eso es todo lo que hay que hacer al método <code>watchPosition()</code>.</p><h3 id="c-mo-agregar-el-objeto-opciones"><strong>Cómo agregar el objeto Opciones</strong></h3><p>Ahora, veamos al objeto opcional <code>options</code> que puedes pasar a los métodos <code>getCurrentPosition()</code> y <code>watchPosition()</code>.</p><p>El objeto <code>options</code> te permite personalizar el comportamiento de los métodos. Hay tres opciones que puedes poner:</p><ul><li><code>enableHighAccuracy</code>: un valor Booleano que instruye al método que provea una posición más precisa. Esto incrementará el consumo de energía. El valor predeterminado es <code>false</code>.</li><li><code>timeout</code>: un valor numérico que representa cuánto espera el método por una respuesta. El valor predeterminado es <code>Infinity</code>, lo que significa que el método esperará hasta que una ubicación esté disponible.</li><li><code>maximumAge</code>: un valor numérico que representa cuánto tiempo la API Geolocation puede enviar los datos de ubicación previos. El valor predeterminado es <code>0</code>, de esa forma la API siempre regresa la ubicación más reciente. Si se define <code>Infinity</code>, entonces la API siempre regresará el primer dato de ubicación recuperado.</li></ul><p>Puedes usar el objeto opciones cuando se llama a los métodos de <code>geolocation</code>.</p><p>Por ejemplo:</p><pre><code class="language-js">const options = {
  enableHighAccuracy: true, // permite alta precisión
  timeout: 300000, // espera 5 minutos
};

function success(position) {
  console.log(position);
}

function error(error) {
  console.log(error);
}

// Ejecuta el método getCurrentPosition() con opciones personalizables
navigator.geolocation.getCurrentPosition(
  success,
  error,
  options
);
</code></pre><p>En el código de arriba, el método <code>getCurrentPosition()</code> usará el modo de alta precisión, y esperará 5 minutos por una respuesta desde el dispositivo.</p><h2 id="resumen"><strong>Resumen</strong></h2><p>La API Geolocation es una API de JavaScript estándar que permite a una aplicación web acceder a los datos de ubicación del usuario.</p><p>Usando los datos de Geolocalización, puedes proveer servicios o contenido relevantes a la ubicación del usuario, tales como el transporte público o el hospital más cercano.</p><p>Si disfrutaste este artículo y quieres aprender más de mí, te recomiendo que mires mi nuevo libro <em><em><a href="https://codewithnathan.com/beginning-modern-javascript">Beginning Modern JavaScript</a></em></em>.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2024/01/beginning-js-cover.png" class="kg-image" alt="Beginning Modern JavaScript" width="600" height="400" loading="lazy"></figure><p>El libro está diseñado para que sea fácil para los principiantes y accesible para cualquiera que quiera aprender JavaScript. Provee una guía amable de paso a paso para ayudarte a entender cómo usar JavaScript para crear una aplicación web dinámica.</p><p>Esta es mi promesa: <em>Sentirás de verdad que entiendes lo que estás haciendo con JavaScript.</em></p><p>¡Nos vemos en otros artículos!</p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Redes HTTP en JavaScript – Manual para Principiantes ]]>
                </title>
                <description>
                    <![CDATA[ HTTP es la columna vertebral del internet moderno. En este curso basado en texto, aprenderás cómo funciona el protocolo HTTP y cómo se usa en el desarrollo web del mundo real. Todos los ejemplos de código para este curso están en JavaScript, pero los conceptos de redes que aprenderás aquí ]]>
                </description>
                <link>https://www.freecodecamp.org/espanol/news/http-networking-in-javascript-handbook-for-beginners/</link>
                <guid isPermaLink="false">663027a97b1bd304018ef761</guid>
                
                    <category>
                        <![CDATA[ HTTPS ]]>
                    </category>
                
                    <category>
                        <![CDATA[ http ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Redes de Computadoras ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Elias Ezequiel Pereyra Gomez ]]>
                </dc:creator>
                <pubDate>Wed, 29 May 2024 18:08:43 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/espanol/news/content/images/2024/04/HTTP-Networking-in-JavaScript-Book-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/http-full-course/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">HTTP Networking in JavaScript – Handbook for Beginners</a>
      </p><p>HTTP es la columna vertebral del internet moderno. En este curso basado en texto, aprenderás cómo funciona el protocolo HTTP y cómo se usa en el desarrollo web del mundo real.</p><p>Todos los ejemplos de código para este curso están en JavaScript, pero los conceptos de redes que aprenderás aquí aplican generalmente para todos los lenguajes de código. <em>Si no estás familiarizado con JavaScript todavía, puede ver <a href="https://boot.dev/learn/learn-javascript">mi curso de JS aquí</a></em>.</p><p>He incluido todo el material de aprendizaje que necesitarás aquí en este artículo, pero si te gustaría una experiencia más práctica, puedes tomar la <a href="https://boot.dev/learn/learn-http">versión interactiva de este curso con desafíos de código en Boot.dev aquí</a>. </p><p>También he publicado una versión en vídeo gratuito de este curso en el canal de Youtube de freeCodeCamp (en inglés):</p><figure class="kg-card kg-embed-card" data-test-label="fitted">
        <div class="fluid-width-video-container">
          <div style="padding-top: 56.17977528089888%;" class="fluid-width-video-wrapper">
            <iframe width="356" height="200" src="https://www.youtube.com/embed/2JYT5f2isg4?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen="" title="Full HTTP Networking Course – Fetch and REST APIs in JavaScript" name="fitvid0" style="box-sizing: inherit; margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 27.5px; vertical-align: middle; position: absolute; top: 0px; left: 0px; width: 720px; height: 404.484px;"></iframe>
          </div>
        </div>
      </figure><p>Si te gusta este vídeo, puedes revisar mis otros tutoriales en mi <a href="https://youtube.com/@bootdotdev">canal de Youtube Boot.dev aquí</a>.</p><p>Con eso dicho, ¡comencemos a aprender sobre HTTP!</p><h2 id="tabla-de-contenidos"><strong><strong><strong>Tabl</strong></strong>a<strong><strong> </strong></strong>de<strong><strong> C</strong></strong>ontenidos</strong></h2><ol><li>¿<a href="#why-http">Por qué HTTP?</a></li><li>¿<a href="#what-is-dns">Qué es DNS?</a></li><li>¿<a href="#what-are-uris">Qué son los URIs?</a></li><li><a href="#async-await">Async/Await</a></li><li><a href="#error-handling">Manejo de Errores</a></li><li><a href="#http-headers">Cabeceras de HTTP</a></li><li>¿<a href="#what-is-json">Qué es JSON?</a></li><li><a href="#http-methods">Métodos HTTP</a></li><li><a href="#url-paths-and-params">Rutas URL y Parámetros</a></li><li><a href="#what-is-https">¿Qué es HTTPs?</a></li></ol><!--kg-card-begin: html--><h2 id="why-http">¿Por qué HTTP?</h2><!--kg-card-end: html--><h3 id="comunicando-en-la-web"><strong>Comunicando en la web</strong></h3><p>Instagram sería bastante terrible si tuvieras que copiar manualmente tus fotos al teléfono de tu amigo cuando quisieras compartirlos. Las aplicaciones modernas necesitan ser capaz de comunicar información <em>entre los dispositivos</em> por internet.</p><ul><li>Gmail no solo almacena tus emails en variables en tu computadora, los almacena en computadoras en sus centros de datos.</li><li>No pierdes los mensajes de Slack si tiras tu computadora en un lago – esos mensajes existen en los <a href="https://es.wikipedia.org/wiki/Servidor_web">servidores</a> de Slack.</li></ul><h3 id="-c-mo-funciona-la-comunicaci-n-web"><strong>¿Cómo funciona la comunicación web?</strong></h3><p>Cuando dos computadores se comunican entre ellos, necesitan usar las mismas reglas. Como hablante inglés no me puedo comunicar verbalmente con un hablante japonés, y de forma similar, dos computadoras necesitan hablar el mismo lenguaje para comunicarse.</p><p>Este "lenguaje" que las computadoras usan se llama un <a href="https://es.wikipedia.org/wiki/Protocolo_de_comunicaciones">protocolo</a>. El protocolo más popular para la comunicación web es <a href="https://developer.mozilla.org/es/docs/Web/HTTP/Overview">HTTP</a>, el cual significa Protocolo de Transferencia de Hipertexto.</p><h3 id="interactuando-con-un-servidor"><strong>Interactuando con un servidor</strong></h3><p>En este curso, un montón de ejemplos de código interactuarán con el <a href="https://pokeapi.co/">PokeAPI</a>. Provee datos sobre Pokemón.</p><p>Aquí hay algo de código que devuelve una lista de Pokemón de la PokeAPI:</p><pre><code class="language-javascript">const pokemonResp = await getItemData()

logPokemons(pokemonResp.results)

async function getItemData() {
  const response = await fetch('https://pokeapi.co/api/v2/pokemon/', {
    method: 'GET',
    mode: 'cors',
    headers: {
      'Content-Type': 'application/json'
    }
  })
  return response.json()
}

function logPokemons(pokemons) {
  for (const pokemon of pokemons) {
    console.log(pokemon.name)
  } 
}</code></pre><p>Cuando ejecutas este código, notarás que ninguno de los datos que se imprimen en la consola fue generado, ¡dentro de nuestro código! Eso se debe a que los datos que devolvimos se envían por internet desde nuestros servidores por medio de HTTP. No te preocupes, explicaré más sobre eso más tarde. </p><h3 id="solicitudes-y-respuestas-http"><strong>Solicitudes y Respuestas HTTP</strong></h3><p>El núcleo de HTTP es un simple sistema de solicitud-respuesta. La computadora "solicitando", también conocido como el "<a href="https://es.wikipedia.org/wiki/Cliente_(inform%C3%A1tica)">cliente</a>", le pide a otra computadora algo de información. Esa computadora, el "<a href="https://es.wikipedia.org/wiki/Servidor">servidor</a>" devuelve una respuesta con la información que fue solicitada.</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://i.imgur.com/ReFw6nN.png" class="kg-image" alt="ReFw6nN" width="925" height="297" loading="lazy"></figure><p>Hablaremos sobre las especificaciones de cómo se formatean las "solicitudes" y "respuestas" luego. Por ahora, solo imagínalo como un simple sistema de pregunta-y-respuesta.</p><ul><li>Solicitud: "¿Cuáles son los ítems en el juego Fantasy Quest?"</li><li>Respuesta: Una lista de los ítems en el juego Fantasy Quest</li></ul><h3 id="http-potencia-a-los-sitios-web"><strong>HTTP potencia a los sitios web</strong></h3><p>Como discutimos, <a href="https://developer.mozilla.org/es/docs/Web/HTTP/Overview">HTTP</a>, o el Protocolo de Transferencia de Hipertexto, es un <a href="https://developer.mozilla.org/es/docs/Glossary/Protocol">protocolo</a> diseñado para transferir información entre computadoras.</p><p>Hay otros protocolos para comunicarse por el internet, pero HTTP es el mas popular y es <em>particularmente genial para los sitios web y aplicaciones web</em>.</p><p>Cada vez que visitas un sitio web, tu navegador realiza una solicitud HTTP a ese servidor del sitio web. El servidor responde con todo el texto, imágenes, e información de estilo que tu navegador necesita para renderizar su lindo sitio web.</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://i.imgur.com/EflKJzq.jpg" class="kg-image" alt="EflKJzq" width="1080" height="1080" loading="lazy"></figure><h3 id="urls-http"><strong>URLs HTTP</strong></h3><p>Un URL, o Localizador de Recursos Uniforme, es esencialmente la dirección de otra computadora, o "servidor" en el internet. Parte de la URL específica cómo alcanzar el servidor, y parte de él le dice al servidor qué información queremos - pero mas sobre eso luego.</p><p>Por ahora, es importante entender que una URL representa una pieza de información en otra computadora a la que queremos acceder. Podemos obtener acceso a él haciendo una <em>solicitud</em>, y leyendo la <em>respuesta</em> con el que el servidor responde.</p><h3 id="c-mo-usar-las-urls-en-http"><strong>Cómo usar las URLs en HTTP</strong></h3><p>El <code>http://</code> al principio de una <a href="https://developer.mozilla.org/es/docs/Learn/Common_questions/Web_mechanics/What_is_a_URL">URL de un sitio web</a> específica que el protocolo <code>http</code> será usado para comunicación.</p><figure class="kg-card kg-image-card"><img src="https://i.imgur.com/6jiaXBn.png" class="kg-image" alt="6jiaXBn" width="368" height="137" loading="lazy"></figure><p>Otros protocolos de comunicación usan URLs también, (por ello "Localizador de Recursos Uniforme"). Por eso necesitamos ser específicos cuando hacemos solicitudes HTTP prefijando la URL con <code>http://</code>.</p><h3 id="repaso-sobre-solicitudes-y-respuestas"><strong>Repaso sobre Solicitudes y Respuestas</strong></h3><ul><li>Un "cliente" es una computadora haciendo una solicitud HTTP</li><li>Un "servidor" es una computadora respondiendo a una solicitud HTTP</li><li>Una computadora puede ser un cliente, un servidor, ambos, o ninguno. "Cliente" y "servidor" son solo palabras que usamos para describir que están haciendo las computadoras dentro de un sistema de comunicación</li><li>Los clientes envían solicitudes y recibe respuestas</li><li>Los servidores reciben solicitudes y envían respuestas</li></ul><h2 id="la-api-fetch-de-javascript"><strong>La API Fetch de JavaScript</strong></h2><p>En este curso, estaremos usando la <a href="https://developer.mozilla.org/es/docs/Web/API/Fetch_API">API fetch</a> incorporada de JavaScript para hacer solicitudes HTTP.</p><p>La función <code>fetch()</code> se pone a nuestra disposición por el lenguaje JavaScript ejecutándose en el navegador. Todo lo que tenemos que hacer es proveerle los parámetros que requiere.</p><h3 id="c-mo-usar-fetch"><strong>Cómo usar<strong><strong> Fetch</strong></strong></strong></h3><pre><code class="language-javascript">const response = await fetch(url, settings)
const responseData = await response.json()
</code></pre><p>Iremos en profundidad sobre las diversas cosas que suceden en esta llamada <code>fetch</code> estándar después, pero cubramos algunas bases por ahora.</p><ul><li><code>response</code> es el dato que es devuelto del servidor</li><li><code>url</code> es la URL a la que le estamos haciendo una solicitud </li><li><code>settings</code> es un objeto que contiene algunas opciones específicas de solicitud</li><li>La palabra clave <code>await</code> le dice a JavaScript que espere hasta que la solicitud vuelva del servidor antes de continuar</li><li><code>response.json()</code> conviertes los datos de respuesta del servidor en un objeto de JavaScript</li></ul><p>Mira si puedes encontrar el problema en este fragmento de código:</p><pre><code class="language-javascript">const pokemonResp = getItemData()

logPokemons(pokemonResp.results)

// el bug (error) está arriba de esta línea

async function getItemData() {
  const response = await fetch('https://pokeapi.co/api/v2/pokemon/', {
    method: 'GET',
    mode: 'cors',
    headers: {
      'Content-Type': 'application/json'
    }
  })
  return response.json()
}

function logPokemons(pokemons) {
  for (const pokemon of pokemons) {
    console.log(pokemon.name)
  } 
}</code></pre><p>Pista: No estamos esperando que los datos sean devueltos por medio de la red.</p><h3 id="los-clientes-web"><strong>Los Clientes Web</strong></h3><p>Un cliente web es un dispositivo realizando solicitudes a un servidor web. Un cliente puede ser de cualquier tipo de dispositivo pero frecuentemente es algo con el que los usuarios interactúan físicamente. Por ejemplo:</p><ul><li>Una computadora de escritorio</li><li>Un teléfono móvil</li><li>Una tablet</li></ul><p>En un sitio web o una aplicación web, le llamamos al dispositivo del usuario el "front-end". Un cliente front-end realiza solicitudes a un servidor back-end.</p><figure class="kg-card kg-image-card"><img src="https://i.imgur.com/zldXGet.jpg" class="kg-image" alt="zldXGet" width="1920" height="1080" loading="lazy"></figure><h3 id="los-servidores-web"><strong>Los Servidores Web</strong></h3><p>A este punto, la mayoría de los datos con los que has trabajado en tu código han sido simplemente generados y almacenados localmente en variables.</p><p>A medida que siempre usarás variables para almacenar y manipular datos mientras tu programa se ejecuta, la mayoría de los sitios web y aplicaciones usan un servidor web para almacenar, ordenar, y servidor esos datos de esa forma se queda por más tiempo que una sesión única, y pueden ser accedidos por múltiples dispositivos.</p><h3 id="escuchando-y-sirviendo-datos"><strong>Escuchando<strong><strong> </strong></strong>y sirviendo<strong><strong> dat</strong></strong>os</strong></h3><p>Similar a cómo un servidor en un restaurante te trae la comida a la mesa, un <a href="https://es.wikipedia.org/wiki/Servidor_web">servidor web</a> sirve recursos web, tales como páginas, imágenes, y otros datos. El servidor se activa y "escucha" solicitudes entrantes constantemente de esa forma en el segundo que recibe una nueva solicitud, puede enviar una respuesta apropiada.</p><h3 id="el-servidor-es-el-back-end"><strong>El servidor es el back-end</strong></h3><p>Mientras el "front-end" de un sitio web o aplicación web es el dispositivo con el que el usuario interactúa, el "back-end" es el servidor que mantiene todos los datos almacenados en un lugar central. Si todavía estás confundido, <a href="https://blog.boot.dev/backend/frontend-vs-backend-meaning/">mira este artículo comparando el desarrollo front-end y back-end</a>. </p><h3 id="un-servidor-es-solo-una-computadora"><strong>Un servidor es solo una computadora</strong></h3><p>"Servidor" es solo el nombre que le damos a una computadora que está tomando el rol de servidor de servidor datos por medio de una conexión red.</p><p>Un buen servidor se activa y está disponible los 24 horas del día, los 7 días de la semana. Mientras tu laptop <em>puede</em> ser usado como un servidor, tiene mas sentido usar una computadora de un centro de datos que está diseñado para estar activo y ejecutándose constantemente.</p><!--kg-card-begin: html--><h2 id="what-is-dns">¿Qué es DNS?</h2><!--kg-card-end: html--><h3 id="direcciones-web"><strong>Direcciones Web</strong></h3><p>En el mundo real, usamos direcciones para ayudarnos a encontrar donde vive un amigo, dónde se encuentra un negocio, o dónde se está organizando una fiesta.</p><p>En computación, los clientes web encuentran otras computadoras a través de internet usando el <a href="https://es.wikipedia.org/wiki/Protocolo_de_internet">Protocolo de Internet o direcciones</a> IP.</p><p>Una dirección IP es una etiqueta numérica que sirve dos funciones principales:</p><ol><li>Dirección de ubicación</li><li>Identificación de Red</li></ol><h3 id="nombres-de-dominio-y-direcciones-ip"><strong>Nombres de Dominio y Direcciones IP</strong></h3><p>Cada dispositivo conectado al internet tiene una dirección IP única. Cuando buscamos por internet, los dominios a la que navegamos todos están asociados con una dirección IP particular.</p><p>Por ejemplo, this URL de Wikipedia apunta a una página sobre cerdos en miniatura: <a href="https://es.wikipedia.org/wiki/Minicerdo"><code>https://es.wikipedia.org/wiki/Minicerdo</code></a>. La porción de dominio del URL es <code>es.wikipedia.org</code>. <code><a href="https://es.wikipedia.org/wiki/Minicerdo">es.wikipedia.org</a></code> se convierte a una dirección IP específica, y esa dirección IP le dice a tu computadora exactamente a dónde comunicarse con esa página de Wikipedia.</p><p>Cloudflare es una compañía tech que provee un servidor HTTP público interesante que podemos usar para buscar la dirección IP de cualquier dominio. Mira este fragmento de código:</p><pre><code class="language-javascript">async function fetchIPAddress(domain) {
  const resp = await fetch(`https://cloudflare-dns.com/dns-query?name=${domain}&amp;type=A`, {
    headers: {
      'accept': 'application/dns-json'
    }
  })
  const respObject = await resp.json()
  for (const record of respObject.Answer) {
    return record.data
  }
  return null
}

const domain = 'api.boot.dev'
const ipAddress = await fetchIPAddress(domain)
if (!ipAddress) {
  console.log('Algo estuvo mal en fetchIPAddress')
} else {
  console.log(`Direccion IP encontrado para el dominio ${domain}: ${ipAddress}`)
}
</code></pre><p>Para repasar, un "nombre de dominio" es parte de un URL. Es la parte que le dice a la computadora <em>dónde se encuentra el servidor en el internet siendo convertido en una dirección IP numérica</em>.</p><p>Cubriremos cómo es usado exactamente una dirección IP por tu computadora para encontrar una ruta al servidor en un curso de redes después. Por ahora, es importante entender que una dirección IP es lo que tu computadora está usando en un nivel bajo para comunicarse en una red.</p><p>Desplegar un sitio web real al internet es en realidad bastante sencillo. Involucra solamente un par de pasos:</p><ol><li>Crear un servidor que hospeda tus archivos del sitio web y conectarlo al internet</li><li>Adquirir un nombre de dominio</li><li>Conectar el nombre de dominio a la dirección IP de tu servidor</li><li>¡Tu servidor es accesible por medio de internet!</li></ol><figure class="kg-card kg-image-card kg-width-wide"><img src="https://i.imgur.com/vjjPt2a.png" class="kg-image" alt="vjjPt2a" width="310" height="163" loading="lazy"></figure><p>Como discutimos, el "nombre de dominio" o "nombre de hospedaje" es parte de una URL. Llegaremos a las otras partes de un URL luego.</p><p>Por ejemplo, la URL <code>https://example.com/path</code> tiene un nombre de host de <code>example.com</code>. Las porciones <code>https://</code> y <code>/path</code> no son parte del mapeo <code>nombre de dominio -&gt; dirección IP</code> que hemos estado aprendiendo.</p><h3 id="usando-la-api-url-en-javascript"><strong>Usando la API URL en JavaScript</strong></h3><p>La API <code>URL</code> está incorporado en JavaScript. Puedes crear un <a href="https://developer.mozilla.org/es/docs/Web/API/URL/URL">nuevo objeto URL</a> como esto:</p><pre><code class="language-js">const urlObj = new URL('https://example.com/example-path')</code></pre><p>Y luego puedes <a href="https://developer.mozilla.org/es/docs/Web/API/URL">extraer solo el nombre de host</a>:</p><pre><code class="language-js">const urlObj.hostname</code></pre><h3 id="repaso-de-dns"><strong>Repaso de DNS</strong></h3><p>Así que hemos hablado sobre nombres de dominio y cuál es su propósito, pero no hemos hablado sobre el sistema que es usado para hacer esa conversión.</p><p><a href="https://www.freecodecamp.org/news/what-is-dns/">DNS</a>, o el "Sistema de Nombre de Dominio", es el directorio de teléfono del internet. Los humanos se conectan a los sitios web a través de <a href="https://es.wikipedia.org/wiki/Dominio_de_internet">nombres de dominio</a>, como <a href="https://boot.dev/">Boot.dev</a>.</p><p>El DNS "resuelve" estos nombres de dominio para encontrar las <a href="https://es.wikipedia.org/wiki/Protocolo_de_internet">direcciones IP</a> asociadas de esa forma los clientes web pueden cargar los recursos para la dirección específica. </p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://i.imgur.com/yvfSbVL.png" class="kg-image" alt="yvfSbVL" width="1024" height="512" loading="lazy"></figure><h3 id="-c-mo-funciona-el-dns"><strong>¿Cómo funciona el DNS?</strong></h3><p>Iremos en mas detalle sobre DNS en un futuro curso, pero para darte una idea simplificada de cómo funciona, introduzcamos ICANN. <a href="https://www.icann.org/">ICANN</a> es una organización sin fines de lucro que gestiona el DNS para todo el internet.</p><p>Cuando tu computadora intenta resolver un nombre de dominio, contacta con uno de los "<a href="https://es.wikipedia.org/wiki/Servidor_ra%C3%ADz">servidores raíz</a>" de ICANN cuyo dirección está incluida en tu configuración de red de la computadora.</p><p>Desde ahí, el servidor puede reunir los registros de dominio para un nombre de dominio específico desde su base de datos de DNS distribuido.</p><p>Si ves al DNS como una guía telefónica, ICANN sería el editor que mantiene la guía telefónica en impresión y disponible.</p><h3 id="sub-dominios"><strong>Sub-dominios</strong></h3><p>Aprendimos cómo un nombre de dominio se traduce a una dirección IP, el cual es solo una computadora en una red - frecuentemente el internet.</p><p>Un sub-dominio prefija un nombre de dominio, permitiendo a un dominio encaminar el tráfico de red a muchos servidores y recursos distintos.</p><p>Por ejemplo, el sitio web <a href="https://boot.dev/">Boot.dev</a> está hospedado en una computadora distinta de nuestro blog. Nuestro blog, encontrado en <a href="https://blog.boot.dev/">blog.boot.dev</a> está hospedado en nuestro sub-dominio "blog".</p><!--kg-card-begin: html--><h2 id="what-are-uris">¿Qué son los URIs?</h2><!--kg-card-end: html--><p>Brevemente tocamos los URLs anteriormente, pero ahora indaguemos un poco más profundo en el tema.</p><p>Un <a href="https://es.wikipedia.org/wiki/Identificador_de_recursos_uniforme">URI</a>, o <em>Identificador</em> de Recursos Uniforme, es una secuencia de caracteres única que identifica a un recurso que es (casi siempre) accedido por medio del internet.</p><p>Así como JavaScript tiene reglas de sintaxis, de la misma forma los URIs. Estas reglas ayudan en asegurar la uniformidad así cualquier programa puede interpretar el significado de la URI de la misma forma.</p><p>Los URIs vienen en dos tipos principales:</p><ul><li><a href="https://es.wikipedia.org/wiki/Localizador_de_recursos_uniforme">URLs</a></li><li><a href="https://es.wikipedia.org/wiki/Nombre_de_Recurso_Uniforme">URNs</a></li></ul><p>Nos enfocaremos específicamente en los URLs en este curso, pero es importante saber que los URLs son solamente un tipo de URI.</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://i.imgur.com/VzqzckC.png" class="kg-image" alt="VzqzckC" width="500" height="394" loading="lazy"></figure><p>Los URLs tienen bastante secciones, algunas de las cuales son requeridos, otros no. Usemos la <a href="https://developer.mozilla.org/es/docs/Web/API/URL/URL">API URL</a> para convertir una URL e imprimir todas las distintas partes. Aprenderemos mas sobre cada parte luego, por ahora, separemos y mostremos un URL.</p><pre><code class="language-js">function printURLParts(urlString) {
  const urlObj = new URL(urlString)
  console.log(`protocolo: ${urlObj.protocol}`)
  console.log(`nombre de usuario: ${urlObj.username}`)
  console.log(`contraseña: ${urlObj.password}`)
  console.log(`nombre de host: ${urlObj.hostname}`)
  console.log(`puerto: ${urlObj.port}`)
  console.log(`nombre de la ruta: ${urlObj.pathname}`)
  console.log(`buscar: ${urlObj.search}`)
  console.log(`hash: ${urlObj.hash}`)
}

const fantasyQuestURL = 'http://dragonslayer:pwn3d@fantasyquest.com:8080/maps?sort=rank#id'
printURLParts(fantasyQuestURL)</code></pre><h3 id="disecci-n-adicional-de-un-url"><strong>Disección adicional de un URL</strong></h3><p>Hay 8 partes principales de un URL, aunque no todas las secciones están presentes siempre. Cada pieza juega un rol específico en ayudar a los cliente localizar el recurso especificado.</p><p>Las 8 secciones son:</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://i.imgur.com/iI3sUVh.png" class="kg-image" alt="iI3sUVh" width="1280" height="720" loading="lazy"></figure><ul><li>El protocolo es requerido</li><li>Los nombres de usuarios y contraseñas son opcionales</li><li>Un dominio es requerido</li><li>El puerto predeterminado para un protocolo dado es usado si uno no fue provisto</li><li>La ruta ( <code>/</code> ) predeterminada es usada si uno no es provisto</li><li>Una solicitud es opcional</li><li>Un fragmento es opcional</li></ul><h3 id="no-te-obsesiones-en-memorizar-esto"><strong>No te obsesiones en memorizar esto</strong></h3><p>Ya que los nombres para las diferentes secciones son usados con frecuencia indistintamente, y ya que no todas las partes del URL están siempre presentes, puede ser difícil mantener las cosas en orden.</p><p>¡No te preocupes en memorizar esto! Intenta familiarizarte con estos conceptos de URL desde un alto nivel. Como cualquier buen desarrollador, puedes buscarlo nuevamente la próxima vez que necesites saber más. </p><h3 id="el-protocolo"><strong>El Protocolo</strong></h3><p>El "protocolo", también referido como el "esquema", es el primero componente de un URL. Su finalidad es definir las reglas mediante los cuales se muestran los datos que se comunican, se codifican, o se formatean.</p><p>Algunos ejemplos de distintos protocolos de URL:</p><ul><li>http</li><li>ftp</li><li>mailto</li><li>https</li></ul><p>Por ejemplo:</p><ul><li><code>http://example.com</code></li><li><code>mailto:noreply@fantasyquest.app</code></li></ul><h3 id="no-todos-los-esquemas-requieren-un-"><strong>No todos los esquemas requieren un "//"</strong></h3><p>El "http" en un URL siempre es seguido por <code>://</code>. Todos los URLs tienen el dos puntos, pero la parte <code>//</code> se incluye solamente para los esquemas que tienen un <a href="https://www.rfc-editor.org/rfc/rfc3986#section-3.2">componente de autoridad</a>.</p><p>Como puedes ver arriba, el esquema <code>mailto</code> no usa un componente de autoridad, ya que no necesita las barras. </p><h3 id="puertos-de-url"><strong>Puertos de URL</strong></h3><p>El puerto en un URL es un punto de virtual donde las conexiones de red son hechas. Los puertos son manejados por un sistema operativo de la computadora y son enumerados desde <code>0</code> a <code>65,535</code>.</p><p>Cada vez que te conectas a otra computadora por medio de una red, te estás conectando a un puerto específico en esa computadora, el cual está siendo escuchado por una pieza de software específica en esa computadora. Un puerto puede ser usado solamente por un programa a la vez, por eso hay demasiados puertos posibles. </p><p>El componente puerto de un URL no es visible frecuentemente cuando se navega en sitios normales en internet, porque el 99% del tiempo estás usando los puertos predeterminados para los esquemas HTTP y HTTPS: <code>80</code> y <code>443</code>, respectivamente.</p><p>Cada vez que no estés usando un puerto predeterminado, necesitas especificarlo en el URL. Por ejemplo, el puerto <code>8080</code> es usado frecuentemente por desarrolladores web cuando están ejecutando su servidor en "modo en prueba" de esa forma no usan el puerto "80" de "producción".</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://i.imgur.com/h3kBsRC.png" class="kg-image" alt="h3kBsRC" width="625" height="129" loading="lazy"></figure><h3 id="rutas-de-url"><strong>Rutas de URL</strong></h3><p>En los primeros días de internet, la ruta de un URL con frecuencia era un reflejo de la ruta del archivo en el servidor al recurso que el cliente estaba solicitando.</p><p>Por ejemplo, si el sitio web <code>https://exampleblog.com</code> tendría un servidor web ejecutándose en su directorio <code>/home</code>, entonces una solicitud al URL <code>https://exampleblog.com/site/index.html</code> podría esperar que el archivo <code>index.html</code> desde dentro del directorio <code>/home/site</code> sea devuelto.</p><p>Los sitios web solían ser muy sencillos. Eran solo una colección de documentos de texto almacenados en un servidor. Un simple servidor de software podría manejar solicitudes HTTP entrantes y responder con los documentos de acuerdo al componente ruta de las URLs.</p><h3 id="en-estos-d-as-no-siempre-es-sobre-el-sistema-de-archivos"><strong>En estos días, no siempre es sobre el sistema de archivos</strong></h3><p>En muchos servidores web modernos, una ruta de URL no es un reflejo de la jerarquía del sistema de archivos del servidor. Las rutas en las URLs son esencialmente otro tipo de parámetro que puede ser pasado al servidor cuando se hace una solicitud.</p><p>Convencionalmente, dos rutas de URL distintas deberían denotar diferentes recursos. Por ejemplo, distintas páginas en un sitio web, o tal vez diferentes tipos de datos desde un servidor de juegos.</p><h3 id="par-metros-de-solicitud"><strong>Parámetros de Solicitud</strong></h3><p>Los parámetros de Solicitud en un URL <em>no</em> siempre están presentes. En el contexto de los sitios web, los parámetros de solicitud con frecuencia son usados para hacer analíticas de marketing o para cambiar una variable en la página web. Con los URLs de sitios web, los parámetros de solicitud <em>raramente</em> cambian que página estás viendo, aunque frecuentemente cambiarán el contenido de la página.</p><p>Con eso dicho, los parámetros de solicitud pueden ser usados para cualquier cosa que el servidor elija, tal como la ruta de URL.</p><h3 id="c-mo-usa-google-los-par-metros-de-solicitud"><strong>Cómo usa Google los parámetros de solicitud</strong></h3><ol><li>Abre una nueva pestaña y ve a <a href="https://google.com/">google.com</a></li><li>Busca "hello world"</li><li>Mira a tu URL actual. Debería comenzar con <code>https://www.google.com/search?q=hello+world</code></li><li>Cambia el URL para que diga <code>https://www.google.com/search?q=hello+universe</code></li><li>Presiona "enter"</li></ol><p>Deberías ver nuevos resultados de búsqueda para la solicitud "hello universe". Google eligió usar los parámetros de solicitud para representar el valor de tu solicitud de buśqueda. Esto tiene sentido - cada página de resultado de búsqueda es <em>esencialmente</em> la misma página en lo que respecta la estructura y el formato - solo te muestra diferentes resultados basado en la solicitud de búsqueda.</p><!--kg-card-begin: html--><h2 id="async-await">Async/Await</h2><!--kg-card-end: html--><p>Probablemente estés familiarizado con código <a href="https://developer.mozilla.org/es/docs/Glossary/Synchronous">síncrono</a>, el cual significa código que se <em>ejecuta en secuencia</em>. Cada línea de código se ejecuta en orden, uno después del otro.</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://i.imgur.com/03FFGu0.png" class="kg-image" alt="03FFGu0" width="587" height="335" loading="lazy"></figure><p><br>Ejemplo de código síncrono:</p><pre><code class="language-js">console.log("Me imprimo primero");
console.log("Me imprimo segundo");
console.log("Me imprimo tercero");
</code></pre><p>El Código asíncrono o async se ejecuta en <em>paralelo</em>. Esto significa que el código mas abajo se ejecuta <em>al mismo tiempo que una línea de código anterior todavía se está ejecutando</em>. Una buena forma de visualizar esto es con la función <a href="https://developer.mozilla.org/es/docs/Web/API/setTimeout">setTimeout()</a> de JavaScript.</p><p><code>setTimeout</code> acepta una función y un número de milisegundos como entradas. Espera hasta que el número de milisegundos ha transcurrido, y luego ejecuta la función que le fue dada.</p><p>Ejemplo de código asíncrono:</p><pre><code class="language-js">jsconsole.log("Me imprimo primero");
setTimeout(() =&gt; console.log("Me imprimo tercero porque estoy esperando 100 milisegundos"), 100);
console.log("Me imprimo segundo");
</code></pre><p>Intenta alterar los tiempos de espera en el código asíncrono abajo para que se impriman los mensajes en el orden correcto:</p><pre><code class="language-js">const craftingCompleteWait = 0
const combiningMaterialsWait = 0
const smeltingIronBarsWait = 0
const shapingIronWait = 0

// No toques nada debajo de esta línea

setTimeout(() =&gt; console.log('Iron Longsword Complete!'), craftingCompleteWait)
setTimeout(() =&gt; console.log('Combining Materials...'), combiningMaterialsWait)
setTimeout(() =&gt; console.log('Smelting Iron Bars...'), smeltingIronBarsWait)
setTimeout(() =&gt; console.log('Shaping Iron...'), shapingIronWait)

console.log('Firing up the forge...')

await sleep(2500)
function sleep(ms) {
  return new Promise((resolve) =&gt; setTimeout(resolve, ms))
}
</code></pre><p>Orden esperado:</p><ol><li>Firing up the forge..</li><li>Smelting Iron Bars...</li><li>Combining Materials...</li><li>Shaping Iron...</li><li>Iron Longsword Complete!</li></ol><h3 id="-por-qu-queremos-c-digo-as-ncrono"><strong>¿Por qué queremos código asíncrono?</strong></h3><p>Intentamos mantener la mayoría de nuestro código síncrono porque es mas fácil de entender, y por lo tanto frecuentemente tiene menos errores. pero a veces <em>necesitamos </em>que nuestro código sea asíncrono.</p><p>Por ejemplo, cada vez que actualices tus opciones de usuario en un sitio web, tu navegador necesitará comunicar esas nuevas opciones al servidor. El tiempo que toma tu solicitud de HTTP para que viaje físicamente a través de todo el cableado del internet es usualmente cerca de los 100 milisegundos. Sería una experiencia muy pobre si tu sitio web se fuera a congelar mientras esperas que la solicitud de red finalice. ¡Inclusive no serías capaz de mover el mouse mientras esperas!</p><p>Haciendo solicitudes de red <em>de manera asíncrona</em>, le permitimos a la página web que ejecute otro código mientras espera la respuesta HTTP que regrese. Esto mantiene a la experiencia de usuario ágil y amigable.</p><p>Como regla general, solamente deberíamos usar código asíncrono cuando lo necesitamos por razones de rendimiento. Código síncrono es mas sencillo.</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://i.imgur.com/03FFGu0.png" class="kg-image" alt="03FFGu0" width="587" height="335" loading="lazy"></figure><h3 id="promesas-en-javascript"><strong>Promesas en JavaScript</strong></h3><p>Una Promesa en JavaScript es muy similar a hacer una promesa en el mundo real. Cuando hacemos una promesa, estamos haciendo un compromiso para algo.</p><p>Por ejemplo, <em>Te prometo explicarte las promesas de JavaScript</em>. Mi promesa para ti tiene dos salidas potenciales: o está concluida, lo que significa que eventualmente te expliqué las promesas, o está rechazada, lo que significa que fallé en mantener mi promesa y no te expliqué las promesas.</p><p>El <a href="https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Global_Objects/Promise">Objeto Promesa</a> representa la eventual conclusión o rechazo de nuestra promesa y mantiene los valores resultantes. Por el momento, mientras esperamos que la promesa se cumpla, nuestro código continúa ejecutándose.</p><p>Las promesas son la forma moderna más popular para escribir código asíncrono en JavaScript. </p><h3 id="c-mo-declarar-una-promesa"><strong>Cómo declarar una Promesa</strong></h3><p>Aquí hay un ejemplo de una promesa que resolverá y devolverá la cadena "resuelto!" o rechazara y regresará la cadena "rechazado!" después de 1 segundo.</p><pre><code class="language-javascript">const promise = new Promise((resolve, reject) =&gt; {
  setTimeout(() =&gt; {
    if (getRandomBool()) {
      resolve("resuelto!")
    } else {
      reject("rechazado!")
    }
  }, 1000)
})

function getRandomBool(){
  return Math.random() &lt; .5
}</code></pre><h3 id="c-mo-usar-una-promesa"><strong>Cómo usar una Promesa</strong></h3><p>Ahora que hemos creado una promesa, ¿cómo lo usamos?</p><p>El objeto <code>Promise</code> tiene .then y .catch lo cual hace más fácil el trabajo. Imagínate a <code>.then</code> como el seguimiento <em>esperado</em> a una promesa, y <code>.catch</code> como el seguimiento "algo estuvo mal".</p><p>Si una promesa <em>resuelve, </em>su función <code>.then</code> se ejecutará. Si la promesa rechaza, su método <code>.catch</code> se ejecutará.</p><p>Aquí hay un ejemplo de usar <code>.then</code> y <code>.catch</code> con la promesa que hicimos arriba:</p><pre><code class="language-js">promise.then((message) =&gt; {
    console.log(`La promesa ${message} finalmente`)
}).catch((message) =&gt; {
    console.log(`La promesa ${message} finalmente`)
})

// imprime:
// La promesa se resolvio finalmente!
// o
// la promesa se rechazo finalmente!</code></pre><h3 id="-por-qu-las-promesas-son-tiles"><strong>¿Por qué las Promesas son útiles?</strong></h3><p>Las Promesas son la forma mas limpia (pero no la única) para manejar el escenario común donde necesitamos realizar solicitudes a un servidor, que es típicamente hecho por medio de una solicitud HTTP. De hecho, la función <a href="https://developer.mozilla.org/es/docs/Web/API/Fetch_API">fetch()</a> que estuvimos usando anteriormente en el curso, ¡devuelve una promesa!</p><h3 id="i-o-o-input-output"><strong>I/O, o "input/output"</strong></h3><p>Casi cada vez que usas una promesa en JavaScript será para manejar algo de I/O. I/O, o input/output, se refiere a cuando nuestro código necesita interactuar con sistema fuera (relativamente) del sencillo mundo de las variables y funciones locales.</p><p>Ejemplos comunes de I/O incluyen:</p><ul><li>Solicitudes HTTP</li><li>Leer archivos desde el disco duro</li><li>Interactuar con un dispositivo Bluetooth</li></ul><p>Las Promesas nos ayudan realizar I/O sin forzar a todo nuestro programa que se congele mientras esperamos una respuesta.</p><h3 id="las-promesas-y-la-palabra-clave-await"><strong>Las Promesas y la palabra clave "await"</strong></h3><p>Hemos usado la palabra clave <a href="https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Operators/await">await</a> unas pocas veces en este curso, así que es tiempo que finalmente entendamos que está pasando por debajo.</p><p>La palabra clave <code>await</code> se usa para <em>esperar a </em>una promesa que se resuelva. Una vez que se ha resuelto, la expresión <code>await</code> devuelve el valor de la <code>Promise</code> resuelta. &nbsp;</p><h3 id="ejemplo-con-el-callback-then"><strong>Ejemplo con el callback .then</strong></h3><pre><code class="language-js">promise.then((message) =&gt; {
  console.log(`Resuelto con ${message}`)
}).</code></pre><h3 id="ejemplo-de-una-promesa-con-await"><strong>Ejemplo de una promesa con await</strong></h3><pre><code class="language-js">const message = await promise
console.log(`Resuelto con ${message}`)</code></pre><h3 id="la-palabra-clave-async"><strong>La palabra clave async</strong></h3><p>Ya que la palabra clave <code>await</code> puede ser usado en lugar de <code>.then()</code> para <em>resolver </em>una promesa, la palabra clave <a href="https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Statements/async_function">async</a> puede ser usado en lugar de <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/Promise">new promise()</a> para <em>crear </em>una nueva promesa.</p><p>Cuando una función es prefijado con la palabra clave <code>async</code>, <em>automáticamente </em>devuelve una promesa. Esa promesa resuelve con el valor que código devuelve desde la función. Puedes imaginarte a <code>async</code> como que "envuelve" tu función dentro de una promesa.</p><p>Estos son equivalentes:</p><h3 id="new-promise-"><strong>new Promise()</strong></h3><pre><code class="language-js">function getPromiseForUserData(){
  return new Promise((resolve) =&gt; {
    fetchDataFromServerAsync().then(function(user){
      resolve(user)
    })
  })
}

const promise = getPromiseForUserData()</code></pre><h3 id="async"><strong>Async</strong></h3><pre><code class="language-js">async function getPromiseForUserData(){
  const user = await fetchDataFromServer()
  return user
}

const promise = getPromiseForUserData()</code></pre><h3 id="-then-vs-await"><strong>.then() vs await</strong></h3><p>En los primeros días de los navegadores web, las promesas y la palabra clave <code>await</code> no existían, así que la única forma de hacer algo de manera asíncrona era usar los callbacks.</p><p>Una "función callback" es una función que le pasas a otra función. Esa función luego llama a tu callback. La función <a href="https://developer.mozilla.org/es/docs/Web/API/setTimeout">setTimeout</a> que hemos usado atrás es un buen ejemplo.</p><pre><code class="language-js">function callbackFunction(){
  console.log("calling back now!")
}
const milliseconds = 1000
setTimeout(callbackFunction, milliseconds)</code></pre><p>Mientras que inclusive la sintaxis <code>.then()</code> es generalmente más fácil de usar que los callbacks sin la API <code>Promise</code>, la sintaxis <code>await</code> los hace aun mas fácil de usar. Deberías usar <code>async</code> y <code>await</code> en vez de <code>.then</code> y <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/Promise">new Promise()</a> como regla general.</p><p>Para demostrar, ¿cuáles de estos es más fácil de entender?</p><pre><code class="language-js">fetchUser.then(function(user){
  return fetchLocationForUser(user)
}).then(function(location){
  return fetchServerForLocation(location)
}).then(function(server){
  console.log(`El servidor es ${server}`)
});</code></pre><pre><code class="language-js">const user = await fetchUser()
const location = await fetchLocationForUser(user)
const server = await fetchServerForLocation(location)
console.log(`El servidor es ${server}`)</code></pre><p>Ambos hacen la misma cosa, pero el ejemplo segundo es, ¡mucho mas fácil de entender! Las palabras claves <code>async</code> y <code>await</code> no fueron lanzados sino hasta <em>después</em> de la API <code>.then</code>, lo cual es la razón de por que hay todavía mucho código <code>.then</code> obsoleto por ahí afuera.</p><!--kg-card-begin: html--><h2 id="error-handling">Manejo de Errores</h2><!--kg-card-end: html--><p>Cuando algo sale mal mientras un programa se ejecuta, JavaScript usa el paradigma <code>try/catch</code> para manejar esos errores. Try/catch es bastante común, y <a href="https://boot.dev/learn/learn-python">Python</a> usa un mecanismo similar.</p><h3 id="primero-se-lanza-un-error"><strong>Primero, se lanza un error</strong></h3><p>Por ejemplo, digamos que intentamos acceder a un propiedad de una variable no definida. JavaScript automáticamente "lanzará" un error.</p><pre><code class="language-js">const speed = car.speed
// El codigo se rompe con el siguiente error:
// "ReferenceError: car no está definido"</code></pre><h3 id="intentando-y-capturando-errores"><strong>Intentando y capturando errores</strong></h3><p>Al envolver ese código en un bloque try/catch, podemos manejar el caso donde <code>car</code> todavía no es definido.</p><pre><code class="language-js">try {
  const speed = car.speed
} catch (err) {
  console.log(`Un error se disparó: ${err}`)
  // el codigo imprime de forma clara:
  // "Un error se disparó: ReferenceError: car no está definido"
}</code></pre><h3 id="bugs-vs-errores"><strong>Bugs vs Errores</strong></h3><p>Manejar errores por medio de try/catch no es lo mismo que depurar. Igualmente, los errores no son lo mismo que los bugs.</p><ul><li>Un buen código sin bugs todavía puede producir errores que son manejados de manera cuidadosa</li><li>Los Bugs son, por definición, pedazitos de código que no están funcionando como se esperaba</li></ul><h3 id="-qu-es-depurar"><strong>¿Qué es Depurar?</strong></h3><p>"Depurar" un programa es el proceso de revisar tu código para encontrar donde no se está comportando como se espera. Depurar es un proceso manual realizado por el desarrollador.</p><p>Ejemplos de depuración:</p><ul><li>Agregar un parámetro faltante a una llamada de función</li><li>Actualizar un URL roto el cual una llamada HTTP estaba intentando de alcanzar</li><li>Arreglar un componente selector de fechas en una aplicación que no se estaba mostrando apropiadamente</li></ul><h3 id="-qu-es-el-manejo-de-errores"><strong>¿Qué es el Manejo de Errores?</strong></h3><p>"Manejo de errores" es código que puede manejar casos específicos <em>esperados</em> en tu programa. El Manejo de Errores es un proceso automatizado que diseñamos en nuestro código de producción para protegerlo de cosas como conexiones de internet débiles, mala entrada de usuario, o bugs en el código de otras personas con los que tenemos que interactuar.</p><p>Ejemplos de manejos de errores:</p><ul><li>Usando un bloque try/catch para detectar un problema con entradas de usuario</li><li>Usando un bloque try/catch para que falle de manera segura cuando no hay una conexión de internet disponible</li></ul><h3 id="brevemente-no-uses-try-catch-para-intentar-manejar-bugs"><strong>Brevemente, no uses try/catch para intentar manejar bugs</strong></h3><p>Si tu código tiene un bug, try/catch no te ayudará. Necesitas ir a encontrar el <a href="https://es.wikipedia.org/wiki/Error_de_software">bug</a> y arreglarlo.</p><p>Si algo que está fuera de tu control puede producir problemas en tu código, deberías usar try/catch u otra lógica de manejo de errores para tratarlo.</p><p>Por ejemplo, podría haber un mensaje en un juego para los usuarios para que se escriba un nuevo nombre de personaje, pero no queremos que usen puntuación. Validar sus entradas y mostrar un mensaje de error si algo está mal sería una forma de "manejar errores".</p><h3 id="async-await-hace-el-manejo-de-errores-mas-f-cil"><strong>async/await hace el manejo de errores mas fácil</strong></h3><p><code>try</code> y <code>catch</code> son la forma estándar de manejar errores en Javascript, el problema es, que la API Promise original con <code>.then</code> no nos permitió hacer uso de los bloques <code>try</code> y <code>catch</code>.</p><p>Afortunadamente, las palabras claves <code>async</code> y <code>await</code> <em>sí</em> lo permite - aún otra razón para elegir la nueva sintaxis.</p><h3 id="el-callback-catch-en-las-promesas"><strong>El callback .catch() en las promesas</strong></h3><p>El método <a href="https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Global_Objects/Promise/catch">.catch()</a> funciona de manera similar al método .then(), pero se dispara cuando un promesa es <em>rechazada </em>en vez de resuelta. </p><h3 id="ejemplo-con-los-callbacks-then-y-catch"><strong>Ejemplo con los callbacks .then y .catch</strong></h3><pre><code class="language-js">fetchUser().then(function(user){
  console.log(`usuario buscado: ${user}`)
}).catch(function(err){
  console.log(`un error fue disparado: ${err}`)
});</code></pre><h3 id="ejemplo-de-una-promesa-con-await-1"><strong>Ejemplo de una promesa con await</strong></h3><pre><code class="language-js">try {
  const user = await fetchUser()
  console.log(`usuario buscado: ${user}`)
} catch (err) {
  console.log(`un error fue disparado: ${err}`)
}</code></pre><p>Como puedes ver, la versión <code>async/await</code> se parece como un <code>try/catch</code> normal de JavaScript.</p><!--kg-card-begin: html--><h2 id="http-headers">Cabeceras de HTTP</h2><!--kg-card-end: html--><p>Una <a href="https://developer.mozilla.org/en-US/docs/Glossary/HTTP_header">cabecera de HTTP</a> permite a los clientes y servidor que pasen información <em>adicional</em> con cada solicitud o respuesta. Las cabeceras son <a href="https://en.wikipedia.org/wiki/Name%E2%80%93value_pair">pares de clave-valor</a> que no distinguen entre mayúsculas y minúsculas que pasan <a href="https://es.wikipedia.org/wiki/Metadatos">metadatos</a> adicionales sobre la solicitud o respuesta.</p><p>Las solicitudes HTTP de un navegador web llevan consigo muchas cabeceras, incluyendo pero no limitado a:</p><ul><li>El tipo de cliente (por ejemplo Google Chrome)</li><li>El Sistema Operativo (por ejemplo Windows)</li><li>El idioma preferido (por ejemplo Inglés US)</li></ul><p>Como desarrolladores, también podemos definir cabeceras personalizadas en cada solicitud.</p><h3 id="la-api-headers"><strong>La API Headers</strong></h3><p>La API <a href="https://developer.mozilla.org/es/docs/Web/API/Headers">Headers</a> nos permite realizar varias acciones en nuestras cabeceras de solicitud y de respuesta tales como devolverlos, establecerlos, y removerlos. Podemos acceder a las cabeceras del objeto a través de las propiedades <code>Request.headers</code> y <code>Response.headers</code>.</p><h3 id="c-mo-usar-las-herramientas-de-desarrollo-del-navegador"><strong>Cómo usar las Herramientas de Desarrollo del Navegador</strong></h3><p>Los navegadores web modernos le ofrecen a los desarrolladores un conjunto poderoso de <em>herramientas de desarrollado</em>. Las Herramientas de Desarrollo son el mejor amigo de los desarrolladores web front-end. Por ejemplo, usando las herramientas de desarrollo puedes:</p><ul><li>Ver la salida en consola de JavaScript de la página web</li><li>Inspeccionar el código HTML, CSS y JavaScript de la página</li><li>Ver solicitudes red y respuestas, juntamente con sus cabeceras</li></ul><p>El método para acceder las herramientas de desarrollo de navegador a navegador. Si estás en Chrome, puedes hacer clic derecho en cualquier parte dentro de una página web y hacer clic en la opción "inspect". Sigue este enlace para mas información en <a href="https://developer.mozilla.org/es/docs/Learn/Common_questions/Tools_and_setup/What_are_browser_developer_tools">cómo acceder a las herramientas de desarrollo</a>.</p><h3 id="la-pesta-a-red"><strong>La pestaña red</strong></h3><p>Mientras todas las pestañas dentro de las herramientas de desarrollo son muy útiles, nos estaremos enfocando en la <em>pestaña de Red</em> en este capitulo así podemos jugar con las cabeceras de HTTP.</p><p>La pestaña Red monitorea la actividad de red del navegador y registrar todas las solicitudes y respuestas que el navegador hace, incluyendo cuanto tiempo toma cada una de esas solicitudes y respuestas para que se procese completamente.</p><p>Si navegas a la pestaña Red y no ves ninguna solicitud aparecer, intenta refrescar la pagina.</p><figure class="kg-card kg-image-card"><img src="https://i.imgur.com/STKdceG.png" class="kg-image" alt="STKdceG" width="580" height="372" loading="lazy"></figure><h3 id="-por-qu-las-cabeceras-son-tiles"><strong>¿Por qué las cabeceras son útiles?</strong></h3><p>Las cabeceras son útiles por varias razones, desde el diseño a la seguridad. Pero mas frecuentemente las cabeceras son usadas como <a href="https://es.wikipedia.org/wiki/Metadatos">metadatos</a> o datos <em>sobre </em>la solicitud.</p><p>Así que, por ejemplo, digamos que queríamos pedir un nivel de jugador de un servidor de juegos. Necesitamos enviar el ID del jugador al servidor de esa forma sabe de qué jugador devuelve la información. Ese ID <em>es mi solicitud</em>, no es información <em>sobre mi solicitud.</em> </p><p>Un buen ejemplo de un caso de uso para las cabeceras es <a href="https://auth0.com/es/intro-to-iam/what-is-authentication">autenticación</a>. Con frecuencia las credenciales de un usuario son incluidas en las cabeceras de solicitud. Las credenciales no tienen que ver mucho con la solicitud <em>en sí misma,</em> sino simplemente autoriza al solicitador ser admitido de hacer la solicitud en cuestión.</p><!--kg-card-begin: html--><h2 id="what-is-json">¿Qué es JSON?</h2><!--kg-card-end: html--><p>Notación de Objeto de JavaScript, o <a href="https://developer.mozilla.org/es/docs/Learn/JavaScript/Objects/JSON">JSON</a>, es un estándar para representar datos <em>estructurados</em> basado en la sintaxis de objetos de JavaScript.</p><p>JSON es comúnmente usado para transmitir datos en aplicaciones web usando HTTP. Las solicitudes HTTP con <code>fetch()</code> que estuvimos usando en este curso han estado devolviendo datos como JSON.</p><h3 id="sintaxis-de-json"><strong>Sintaxis de JSON </strong></h3><p>Porque ya entendimos cómo lucen los objetos de JavaScript, entender JSON es fácil. JSON es solo un objeto de JavaScript en cadenas. Lo siguiente son datos en JSON válidos:</p><pre><code class="language-json">{
    "movies": [
        {
            "id": 1,
            "genre": "Action",
            "title": "Iron Man",
            "director": "Jon Favreau"
        },
        {
            "id": 2,
            "genre": "Action",
            "title": "The Avengers",
            "director": "Joss Whedon"
        }
    ]
}</code></pre><h3 id="c-mo-convertir-respuestas-http-a-json"><strong>Cómo convertir Respuestas HTTP a JSON</strong></h3><p>JavaScript nos provee algunas herramientas fáciles para ayudarnos a trabajar con JSON. Después de hacer una solicitud HTTP con la <a href="https://developer.mozilla.org/es/docs/Web/API/Fetch_API">API fetch()</a>, obtenemos un <a href="https://developer.mozilla.org/es/docs/Web/API/Response">objeto Response</a>. Ese objeto respuesta nos ofrece algunos métodos que nos ayudan en interactuar con la respuesta.</p><p>Un método como tal es el método .json(). El método <code>.json()</code> toma el <a href="https://es.wikipedia.org/wiki/Streaming">stream</a> respuesta devuelto por una solicitud con fetch y devuelve una <a href="https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Global_Objects/Promise">Promesa</a> que se convierte en un objeto JavaScript desde el cuerpo JSON de la respuesta HTTP.</p><pre><code class="language-js">const resp = await fetch(...)
const javascriptObjectResponse = await resp.json()</code></pre><p>Es importante notar que el resultado del método <code>.json()</code> <em>NO</em> es JSON. Es el resultado de tomar datos JSON desde el cuerpo de la respuesta HTTP y convertir la entrada en un Objeto JavaScript.</p><h3 id="revisi-n-de-json"><strong>Revisión de JSON</strong></h3><p>JSON es una <em>representación en cadena</em> de un objeto JavaScript, lo cual lo hace perfecto para guardar en un archivo o enviarlo en una solicitud HTTP.</p><p>Recuerda, un objeto JavaScript es algo que existe solamente dentro de tus variables del programa. Si queremos enviar un objeto fuera de nuestro programa, por ejemplo, a través de internet en una solicitud HTTP, necesitamos convertirlo a JSON primero.</p><h3 id="no-es-usado-solo-en-javascript"><strong>No es usado solo en JavaScript</strong></h3><p>Solo porque JSON significa Notación de Objeto de <em>JavaScript</em> no significa que ¡solamente es usado por JavaScript! JSON es un estándar común que es reconocido y soportado por todos los lenguajes principales de programación.</p><p>Por ejemplo, aunque la API back-end de Boot.dev está escrito en <a href="https://www.boot.dev/learn/learn-golang">Go</a>, todavía usamos <a href="https://blog.boot.dev/golang/json-golang/">JSON</a> como el formato de comunicación entre el front-end y el back-end.</p><p>A propósito, este curso ha tratado sobre interactuar con servidores back-end desde una perspectiva de front-end. Pero si estás interesado sobre cómo te puedes convertir en un ingeniero back-end, <a href="https://blog.boot.dev/backend/become-backend-developer/">mira esta guía que he preparado</a>. Como referencia, le toma a la mayoría de gente <a href="https://blog.boot.dev/backend/how-long-to-become-backend-dev/">entre 6-18 meses</a> para aprender lo suficiente para tener su primer <a href="https://blog.boot.dev/backend/backend-job-description/">trabajo de back-end</a>.</p><h3 id="casos-de-uso-de-json-comunes"><strong>Casos de uso de JSON Comunes</strong></h3><ul><li>En solicitudes HTTP y cuerpos de respuesta</li><li>Como formatos para archivos de texto. Archivos <code>.json</code> son usados frecuentemente como archivos de configuración</li><li>En bases de datos NoSQL como MongoDB, ElasticSearch, y Firestore</li></ul><h3 id="c-mo-pronunciar-json"><strong>Cómo pronunciar JSON</strong></h3><p>Lo pronuncio "Yey-sawn", pero también he oído a la gente pronunciarlo "Yason", justo como su nombre.</p><h3 id="c-mo-enviar-json"><strong>Cómo enviar JSON</strong></h3><p>JSON no es algo que obtenemos del servidor, también podemos <em>enviar</em> datos JSON.</p><p>En JavaScript, dos de los métodos principales a los que tenemos acceso son <code>JSON.parse()</code>, y <code>JSON.stringify()</code>.</p><h4 id="json-stringify-"><strong><code>JSON.stringify()</code></strong></h4><p><code>JSON.stringify()</code> es útil particularmente <em>para</em> enviar JSON.</p><p>Como podrías esperar, el método <code>stringify()</code> de JSON hace lo opuesto de convertir. Toma un objeto JavaScript o un valor como entrada y lo convierte en una cadena. Esto es útil cuando necesitamos serializar los objetos en cadenas para enviarlos a nuestro servidor o almacenarlos en una base de datos.</p><p>Aquí hay un fragmento de código que envía una <a href="https://es.wikipedia.org/wiki/Carga_%C3%BAtil_(inform%C3%A1tica)">carga útil</a> (payload en inglés) JSON a un servidor remoto:</p><pre><code class="language-javascript">async function sendPayload(data, headers) {
  const response = await fetch(url, {
    method: 'POST',
    mode: 'cors',
    headers: headers,
    body: JSON.stringify(data)
  })
  return response.json()
}
</code></pre><h3 id="c-mo-convertir-json"><strong>Cómo convertir JSON</strong></h3><p>El método <a href="https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse">JSON.parse()</a> toma una cadena JSON como entrada y construye el valor/objeto JavaScript descrito por la cadena. Esto nos permite trabajar con el JSON como si fuese un objeto JavaScript normal.</p><p>Viendo que los objetos JSON tienen una estructura tipo árbol, puede ser útil para saber cómo <a href="https://blog.boot.dev/javascript/how-to-recursively-traverse-objects/">recorrerlos recursivamente</a> si es necesario.</p><pre><code class="language-js">const json = '{"title": "Avengers Endgame", "Rating":4.7, "inTheaters":false}';
const obj = JSON.parse(json)

console.log(obj.title)
// Avengers Endgame</code></pre><h3 id="xml"><strong>XML</strong></h3><p>No podemos hablar sobre JSON sin mencionar a <a href="https://es.wikipedia.org/wiki/Extensible_Markup_Language">XML</a>. Lenguaje de Marcado Extensible, o <code>XML</code> es un formato basado en texto para representar información estructurada, así como JSON - solo que se ve un poco distinto.</p><p>XML es un lenguaje de marcado como <a href="https://es.wikipedia.org/wiki/HTML">HTML</a>, pero es mas generalizado en el hecho de que <em>no</em> usa etiquetas predefinidas. Así como las claves de objetos JSON puede ser llamados de cualquier forma, las etiquetas XML también pueden tener cualquier nombre.</p><pre><code class="language-xml">&lt;root&gt;
  &lt;id&gt;1&lt;/id&gt;
  &lt;genre&gt;Action&lt;/genre&gt;
  &lt;title&gt;Iron Man&lt;/title&gt;
  &lt;director&gt;Jon Favreau&lt;/director&gt;
&lt;/root&gt;</code></pre><p>Los mismos datos en formato JSON:</p><pre><code class="language-json">{
  "id": "1",
  "genre": "Action",
  "title": "Iron Man",
  "director": "Jon Favreau"
}</code></pre><h3 id="-por-qu-usar-xml"><strong>¿Por qué usar XML?</strong></h3><p>XML y JSON ambos logran tareas similares, así que, ¿cuál deberías usar?</p><p>XML solía ser usado para las mismas cosas que JSON hoy en día es usado. Archivos de configuración, cuerpos HTTP, y otros casos de uso de transferencia de datos pueden funcionar sin problemas usando JSON o XML. Este es mi consejo: hablando de forma general, si JSON funciona, deberías preferirlo por sobre XML en estos días. JSON es mas liviano, mas fácil de leer, y tiene mejor soporte en la mayoría de lenguajes de programación modernos.</p><p>Hay algunos casos donde XML podría ser lo mejor, o tal vez inclusive la opción necesaria, pero esos casos serán raros.</p><!--kg-card-begin: html--><h2 id="http-methods">Métodos HTTP</h2><!--kg-card-end: html--><p>HTTP define un conjunto de <a href="https://developer.mozilla.org/es/docs/Web/HTTP/Methods">métodos</a> que usamos cada vez que hacemos una solicitud. Hemos usado algunos de estos métodos en ejercicios previos, pero es tiempo de profundizarlos para entender las diferencias y casos de uso que hay por detrás de los distintos métodos.</p><h3 id="el-m-todo-get"><strong>El método GET</strong></h3><p>El <a href="https://www.freecodecamp.org/news/javascript-get-request-tutorial/">método GET</a> se usa para "obtener" una representación de un recurso especificado. No estás quitando los datos del servidor, sino que obtienes una representación, o copia, del recurso en su estado actual.</p><p>Una solicitud get es considerado un método <a href="https://developer.mozilla.org/en-US/docs/Glossary/Safe/HTTP">seguro</a> para llamar mútiples veces porque no altera el estado del servidor.</p><h3 id="como-hacer-una-solicitud-get-usando-la-api-fetch"><strong>Como hacer una Solicitud GET usando la API Fetch</strong></h3><p>El método fetch() acepta un parámetro objeto <code>init</code> opcional como su segundo argumento que podemos usar para definir cosas como:</p><ul><li><code>method</code>: El método HTTP de la solicitud, como <code>GET</code></li><li><code>headers</code>: Las cabeceras para enviar</li><li><code>mode</code>: Usado para seguridad, hablaremos sobre esto en cursos futuros</li><li><code>body</code>: El cuerpo de la solicitud. Frecuentemente codificado como JSON</li></ul><p>Ejemplo de una solicitud <code>GET</code> usando fetch:</p><pre><code class="language-js">await fetch(url, {
  method: 'GET',
  mode: 'cors',
  headers: {
    'sec-ch-ua-platform': 'macOS'
  }
})</code></pre><h3 id="-por-qu-usamos-m-todos-http"><strong>¿Por qué usamos métodos HTTP?</strong></h3><p>Como mencionamos antes, el propósito primario de los métodos HTTP es indicar al servidor lo que queremos hacer con el recurso que intentamos interactuar.</p><p>Al final del día, un método HTTP es solo una cadena, como <code>GET</code>, <code>POST</code>, <code>PUT</code>, o <code>DELETE</code>. Pero por <em>convención,</em> los desarrolladores back-end casi siempre escribe su código de servidor de manera que los métodos corresponden con diferentes acciones "CRUD".</p><p>Las acciones "CRUD" son:</p><ul><li>Create (Crear)</li><li>Read (Leer)</li><li>Update (Actualizar)</li><li>Delete (Eliminar)</li></ul><p>La mayor parte de la lógica en la mayoría de las aplicaciones web es la lógica "CRUD". La interfaz web permite a los usuarios crear, leer, actualizar y eliminar varios recursos.</p><p>Imagínate un sitio de red social - los usuarios básicamente crean, leen, actualizan y eliminar sus post sociales. También están creando, leyendo, actualizando y eliminando sus cuentos de usuario. ¡Es CRUD hasta el final!</p><p>Como sucede, los 4 métodos HTTP mas comunes se mapean muy bien a las acciones CRUD:</p><ul><li><code>POST</code> = crear</li><li><code>GET</code> = leer</li><li><code>PUT</code> = actualizar</li><li><code>DELETE</code> = eliminar</li></ul><h3 id="solicitudes-post"><strong>Solicitudes POST</strong></h3><p>Una <a href="https://www.freecodecamp.org/news/javascript-post-request-how-to-send-an-http-post-request-in-js/">solicitud POST HTTP</a> envía datos a un servidor, típicamente para crear un nuevo recurso. El <code>body</code> de la solicitud es el <em>payload </em>que está siendo enviado al servidor con la solicitud. Su tipo es indicado por la cabecera <code>Content-Type</code>.</p><h3 id="c-mo-agregar-un-body"><strong>Cómo agregar un </strong><code><strong>body</strong></code></h3><p>El <code>body</code> de la solicitud es el <em>payload</em> que está siendo enviado al servidor con la solicitud. Su tipo es indicado por la cabecera <code>Content-Type</code> - para nosotros, eso va a ser JSON.</p><p>Las solicitudes <code>POST</code> <em>no </em>son generalmente seguros para llamar múltiples veces, porque altera el estado del servidor. No querrías crear accidentalmente 2 cuentas para el mismo usuario, por ejemplo. </p><pre><code class="language-js">await fetch(url, {
  method: 'POST',
  mode: 'cors',
  headers: {
    'Content-Type': 'application/json'
  },
  body: JSON.stringify(data)
})</code></pre><h3 id="c-digos-de-estado-http"><strong>Códigos de Estado HTTP</strong></h3><p>Ahora que entendemos cómo escribir solicitudes HTTP desde cero, necesitamos aprender cómo asegurar que el servidor está haciendo lo que queremos.</p><p>Anteriormente en el curso, aprendimos cómo acceder a las <em>herramientas de desarrollo</em> del navegador y usar esas herramientas para inspeccionar las solicitudes HTTP. Podemos usar el mismo proceso para verificar las solicitudes que estamos haciendo y verificar lo que están haciendo así podemos abarcar problemas potenciales.</p><p>Cuando se mira a las solicitudes, podemos ver el <code>Código de Estado</code> de la solicitud para obtener alguna información si la solicitud fue exitosa o no.</p><ul><li><code>100-199</code>: Respuestas informativas. Estos son muy raros</li><li><code>200-299</code>: Respuestas exitosas. Con suerte, ¡la mayoría de las respuestas son 200's!</li><li><code>300-399</code>: Mensajes de redirección. Estos sin típicamente invisibles porque el navegador o el cliente HTTP automáticamente hará la redirección</li><li><code>400-499</code>: Errores de cliente. Verás a estos frecuentemente, especialmente cuando intentes depurar una aplicación cliente</li><li><code>500-599</code>: Errores de servidor. Verás a estos a veces, usualmente solo si hay un error en el servidor</li></ul><p>Aquí hay algunos de los códigos de estado mas comunes, pero puedes ver una <a href="https://developer.mozilla.org/es/docs/Web/HTTP/Status">lista completa aquí</a> si estás interesado.</p><ul><li><code>200</code> - OK. Este es de lejos el código mas común, significa que todo funcionó como se esperaba.</li><li><code>201</code> - Creado. Esto significa que un recurso fue creado exitosamente. Típicamente en respuesta a una solicitud <code>POST</code>.</li><li><code>301</code> - Movido permanentemente. Esto significa que el recurso fue movido a un nuevo lugar, y la respuesta incluirá donde se encuentra ese nuevo lugar. Los sitios web frecuentemente usan redirecciones <code>301</code> cuando cambian su nombre de domino, por ejemplo.</li><li><code>400</code> - Mala solicitud. Un error general indicando al cliente que cometió un error en la solicitud.</li><li><code>403</code> - No autorizado. Esto significa que el cliente no tiene los permisos correctos. Tal vez no incluyeron una cabecera de autorización requerida, por ejemplo.</li><li><code>404</code> - No encontrado. Verás esto en sitios web con bastante frecuencia. Significa que el recurso no existe.</li><li><code>500</code> - Error de servidor Interno. Esto significa que algo estuvo mal en el servidor, posiblemente un error en su final.</li></ul><h3 id="no-necesitas-memorizarlos"><strong>No necesitas memorizarlos</strong></h3><p>Necesitas saber lo básico, como "2XX está bien", "4XX es un error de cliente", y "5XX es un error de servidor". Con eso dicho, no necesitas memorizar todos los códigos, son fáciles de buscar.</p><figure class="kg-card kg-image-card"><img src="https://i.imgur.com/FJl2z9O.jpg" class="kg-image" alt="FJl2z9O" width="549" height="454" loading="lazy"></figure><p>¡Miremos algunos códigos de estado!</p><p>La propiedad <code>.status</code> en un objeto Response te dará el código. Aquí hay un ejemplo:</p><pre><code class="language-js">async function getStatusCode(url, headers) {
  const response = await fetch(url, {
    method: 'GET',
    mode: 'cors',
    headers: headers
  })
  return response.status
}</code></pre><h3 id="m-todo-put"><strong>Método PUT</strong></h3><p>El <a href="https://developer.mozilla.org/es/docs/Web/HTTP/Methods/PUT">método PUT HTTP</a> crea un nuevo recurso o reemplaza una representación del recurso objetivo con los contenidos del <code>body</code> de la solicitud. En corto, actualiza la propiedad de una solicitud.</p><pre><code class="language-js">await fetch(url, {
   method: 'PUT',
   mode: 'cors',
   headers: {
   'Content-Type': 'application/json'
   },
   body: JSON.stringify(data)
})</code></pre><h3 id="post-vs-put"><strong>POST vs PUT</strong></h3><p>Tal vez estás pensando que <code>PUT</code> es similar a <code>POST</code> o <code>PATCH</code>, y francamente, tendrías razón. La principal diferencia es que PUT está destinado a ser <a href="https://developer.mozilla.org/en-US/docs/Glossary/Idempotent">idempotente</a>, significa que múltiples solicitudes PUT idénticos deberían tener el mismo efecto en el servidor.</p><p>En contraste, varias solicitudes <code>POST</code> idénticas tendrían efectos secundarios adicionales, tales como crear múltiples copias del recurso.</p><h3 id="patch-vs-put-http"><strong>Patch vs PUT HTTP </strong></h3><p>Podrías encontrarte con los métodos <a href="https://developer.mozilla.org/es/docs/Web/HTTP/Methods/PATCH">PATCH</a> de vez en cuando. Si bien no es tan común como los otros métodos, como <code>PUT</code>, es importante conocerlo y saber qué hace. El método <code>PATCH</code> pretende modificar <em>parcialmente</em> un recurso.</p><p>Larga historia corta, <code>PATCH</code> no es tan popular como <code>PUT</code>, y muchos servidores, inclusive si permiten actualizaciones parciales, aún usará el método <code>PUT</code> para eso. </p><h3 id="http-delete"><strong>HTTP Delete </strong></h3><p>El método <code>DELETE</code> hace exactamente lo que esperarías: es usado convencionalmente eliminar un recurso especificado.</p><pre><code class="language-js">// Esto elimina la ubicación con ID: 52fdfc07-2182-454f-963f-5f0f9a621d72
const url = 'https://example-api.com/locations/52fdfc07-2182-454f-963f-5f0f9a621d72'

await fetch(url, {
  method: 'DELETE',
  mode: 'cors'
})</code></pre><!--kg-card-begin: html--><h2 id="url-paths-and-params">Rutas URL y Parámetros</h2><!--kg-card-end: html--><p>La Ruta URL viene justo después del dominio (o puerto si uno es provisto) en una cadena URL.</p><p>En esta URL, la rua es <code>/root/next</code>: <code>http://testdomain.com/root/next</code>.</p><h3 id="qu-significaban-las-rutas-en-el-internet-primitivo"><strong>Qué significaban las rutas en el internet primitivo</strong></h3><p>En los primeros días del internet, y a veces aún hoy en día, muchos servidores web simplemente servían archivos sin procesar desde el sistema de archivos del servidor.</p><p>Por ejemplo, si quería ser capaz de acceder algunos documentos de texto, podría comenzar un servidor web en mi directorio <code>documentos</code>. Si hacías una solicitud a mi servidor, serías capaz de acceder a distintos documentos usando la ruta que coincidía con mi estructura de archivos local.</p><p>Si tendría un archivo en mi <code>/documentos/hello.txt</code> local, podrías accederlo haciendo una solicitud <code>GET</code> a <code>http://example.com/documentos/hello.txt</code>.</p><h3 id="c-mo-son-usados-las-rutas-hoy-en-d-a"><strong>Cómo son usados las rutas hoy en día</strong></h3><p>La mayoría de los servidores web modernos no usan ese simple mapeo de <code>ruta URL</code> -&gt; <code>ruta de archivo</code>. Técnicamente, una ruta URL es solo una cadena con el que el servidor web puede hacer lo que quiera, y los sitios web modernos toman ventaja de esa flexibilidad.</p><p>Algunos ejemplos comunes de para qué se usan las rutas incluyen:</p><ul><li>La jerarquía de las páginas en un sitio web, si refleja o no una estructura de archivos del servidor</li><li>Los parámetros se pasan en una solicitud HTTP, como un ID de un recurso</li><li>La versión de la API</li><li>El tipo de recurso siendo solicitado</li></ul><h3 id="apis-restful"><strong>APIs RESTful </strong></h3><p><a href="https://developer.mozilla.org/es/docs/Glossary/REST">Transferencia de Estado Representacional, o REST</a>, es una convención popular que el servidor HTTP sigue. No todas las APIs HTTP son "APIs REST", o "RESTful", pero es <em>muy</em> común.</p><p>Los servidores RESTful siguen un conjunto de reglas flexibles que facilita construir APIs web predecibles y confiables. REST es más o menos un conjunto de convenciones sobre cómo HTTP <em>debería</em> ser usado.</p><h3 id="separado-y-agn-stico"><strong>Separado y agnóstico</strong></h3><p>La gran idea detrás de REST es que los recursos son transferidos por medio de interacciones de cliente/servidor reconocidas y agnósticas del lenguaje. </p><p>Un estilo RESTful significa que la implementación del cliente y del servidor puede ser hecho independientemente el uno del otro, siempre y cuando algunos estándares sencillos, como los nombres de los recursos disponibles, han sido establecidos.</p><h3 id="sin-estado"><strong>Sin estado</strong></h3><p>Una arquitectura RESTful es sin estado. Esto significa que el servidor no necesita saber en qué estado está el cliente, ni el cliente necesita saber en qué estado está el servidor.</p><p>Statelessness en REST es re-asegurado al interactuar con recursos en vez de comandos. Ten en mente, esto no significa que las aplicaciones son sin estado - al contrario, ¿qué significaría "actualiza un recurso" si el servidor no mantenía registro de su estado?</p><h3 id="las-rutas-en-rest"><strong>Las Rutas en REST</strong></h3><p>En una API RESTful, la última sección del <code>path</code> de un URL debería especificar cuál recurso está siendo accedido. Luego, como hablamos en la sección "métodos", dependiendo en si la solicitud es un <code>GET</code>, <code>POST</code>, <code>PUT</code> o <code>DELETE</code>, el recurso es leído, creado, actualizado, o eliminado.</p><p>Por ejemplo, en el <a href="https://pokeapi.co/">PokeAPI</a>:</p><ul><li><a href="https://pokeapi.co/api/v2/pokemon/"><code>https://pokeapi.co/api/v2/pokemon/</code></a></li><li><a href="https://pokeapi.co/api/v2/pokemon/"><code>https://pokeapi.co/api/v2/location/</code></a></li></ul><p>La primer parte de la ruta especifica que estamos interactuando con una API en vez de un sitio web. La siguiente parte especifica la versión, en este caso, versión 2, o <code>v2</code>.</p><p>Finalmente, la última parte denota qué recurso está siendo accedido, sea un <code>location</code> o <code>pokemon</code>.</p><h3 id="par-metros-de-solicitud-url"><strong>Parámetros de Solicitud URL</strong></h3><p>Los parámetros de solicitud de URL aparecen después en la estructura URL pero <em>no</em> siempre están presentes - son opcionales. Por ejemplo:</p><p><a href="https://www.google.com/search?q=boot.dev">https://www.google.com/search?q=boot.dev</a></p><p><code>q=boot.dev</code> es un parámetro de solicitud. Como las cabeceras, los parámetros de solicitud son pares <code>clave / valor</code>. En este caso, <code>q</code> es la clave y <code>boot.dev</code> es el valor.</p><h3 id="la-documentaci-n-de-un-servidor-http"><strong>La Documentación de un Servidor HTTP</strong></h3><p>Te estarás preguntando:</p><blockquote>¿Cómo se supone que memorice cómo funcionan todos estos servidores distintos???</blockquote><p>Las buenas noticias es que <em>no lo necesitas</em>. Cuando trabajas con un servidor back-end, es la responsabilidad de los desarrolladores del servidor que te provean con instrucciones, o <em>documentación</em> que explica cómo interactuar con él. </p><p>Por ejemplo, la documentación debería decirte:</p><ul><li>El dominio del servidor</li><li>Los recursos con los que interactuas (rutas HTTP)</li><li>Los parámetros de solicitud soportados</li><li>Los métodos HTTP soportados</li><li>Cualquier otra cosa que necesitarás saber para trabajar con el servidor</li></ul><figure class="kg-card kg-image-card"><img src="https://i.imgur.com/GIlWhYF.jpg" class="kg-image" alt="GIlWhYF" width="500" height="553" loading="lazy"></figure><h3 id="el-servidor-tiene-control"><br><strong>El servidor tiene control</strong></h3><p>Como mencionamos antes, el servidor tiene control total sobre cómo la ruta en un URL es interpretado y usado en una solicitud. Lo mismo es para los parámetros de solicitud.</p><p>No todos los servidores soportan parámetros de solicitud para cada tipo de solicitud, depende, así que necesitarás consultar la documentación.</p><h3 id="m-ltiples-par-metros-de-solicitud"><strong>Múltiples Parámetros de Solicitud</strong></h3><p>Mencionamos que los parámetros de solicitud son pares <code>clave/valor</code> - que significa que podemos tener múltiples pares.</p><p><code>http://example.com?firstName=lane&amp;lastName=wagner</code></p><p>En el ejemplo de arriba:</p><ul><li><code>firstName</code> = <code>lane</code></li><li><code>lastName</code> = <code>wagner</code></li></ul><p>El <code>?</code> separa los parámetros de solicitud del resto del URL. El <code>&amp;</code> luego es usado para separar <em>cada par</em> de parámetros solicitud después de eso.</p><p>Por ejemplo, haz que esta solicitud que limite el número de Pokemons devuelto del PokeAPI a <code>2</code>:</p><pre><code>https://pokeapi.co/api/v2/location/?limit=2</code></pre><!--kg-card-begin: html--><h2 id="what-is-https">¿Qué es HTTPs?</h2><!--kg-card-end: html--><p>el protocolo de Transferencia de Hipertexto <em>Seguro</em> o <a href="https://www.freecodecamp.org/news/what-is-https-http-vs-https-meaning-and-how-it-works/">HTTPS</a> es una extensión del protocolo HTTP. HTTPS protege la transferencia de datos entre el cliente y el servidor <a href="https://developer.mozilla.org/es/docs/Glossary/Encryption">encriptando</a> toda la comunicación.</p><p>HTTPS permite a un cliente para que comparta información sensitiva sin peligro con el servidor a través de una solicitud HTTP, tales como información de tarjeta de crédito, contraseñas, o números de cuentas de banco.</p><p>HTTPS requiere que el cliente use <a href="https://developer.mozilla.org/en-US/docs/Glossary/SSL">SSL</a> o <a href="https://www.freecodecamp.org/news/what-is-tls-transport-layer-security-encryption-explained-in-plain-english/">TLS</a> para proteger las solicitudes y el tráfico encriptando la información en la solicitud. HTTPS es solo HTTP con seguridad extra.</p><figure class="kg-card kg-image-card kg-width-wide kg-card-hascaption"><img src="https://i.imgur.com/iOkQUdG.png" class="kg-image" alt="iOkQUdG" width="517" height="487" loading="lazy"><figcaption>HTTP vs HTTPS</figcaption></figure><h3 id="https-mantiene-tus-mensajes-privados-pero-no-tu-identidad"><strong>HTTPS mantiene tus mensajes privados, pero no tu identidad</strong></h3><p>No cubriremos <em>cómo</em> funciona la encriptación en este curso, pero lo haremos en próximos cursos. Por ahora, es importante notar que mientras HTTPS encripta <em>lo que estás diciendo</em>, no protege necesariamente <em>quién eres</em>. Herramientas como <a href="https://nordvpn.com/es-mx/what-is-a-vpn/">VPNs</a> son necesarios para permanecer en línea de manera anónima.</p><h3 id="https-se-asegura-que-est-s-hablando-a-la-persona-correcta-o-servidor-"><strong>HTTPS se asegura que estás hablando a la persona correcta (o servidor)</strong></h3><p>Además de encriptar la información dentro de una solicitud, HTTPS usa <a href="https://es.wikipedia.org/wiki/Firma_digital">firmas digitales</a> para probar que te estás comunicando con el servidor con el que piensas.</p><p>Si un hacker fuera a interceptar una solicitud HTTPS tocando un cable de red, no serían capaz de pretender exitosamente que son el servidor web de tu banco.</p><p>Asumiendo que un servidor soporta HTTPs, lo usas para cambiar simplemente el protocolo en tu su URL de solicitud: <code>https://boot.dev</code></p><h3 id="-quieres-poner-en-pr-ctica-lo-que-has-aprendido-con-un-proyecto"><strong>¿Quieres poner en práctica lo que has aprendido con un proyecto?</strong></h3><p>Mira esta <a href="https://www.boot.dev/learn/build-web-crawler-javascript">guía de proyecto donde construirás un web crawler en JavaScript</a> desde cero. Te hará usar la API Fetch y convirtiendo datos JSON, ¡como un pro! No necesitas construir el proyecto, pero es una excelente forma de practicar lo que has aprendido.</p><h2 id="-felicidades-en-llegar-hasta-el-final-"><strong>¡Felicidades en llegar hasta el final!</strong></h2><p>Si estás interesado en hacer las asignaciones de código interactivos y cuestionarios para este curso puedes revisar el <a href="https://www.boot.dev/learn/learn-object-oriented-programming">curso de Aprender HTTP</a> en <a href="https://boot.dev/">Boot.dev</a>.</p><p>Este curso es una parte de mi <a href="https://boot.dev/tracks/backend">trayectoria profesional desarrollador full back-end</a>, hecho de otros cursos y proyectos si te interesa verlos.</p><p>Si quieres ver otro contenido que creo relacionado al desarrollo web, mira algunos de mis enlaces abajo:</p><ul><li><a href="https://twitter.com/wagslane">Lane en Twitter</a></li><li><a href="https://youtube.com/@bootdotdev">Lane en YouTube</a></li><li><a href="https://wagslane.dev/">Sitio Personal de Lane</a></li></ul> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Tutorial Vite.js – Cómo instalar y usar Vite en tus proyectos web ]]>
                </title>
                <description>
                    <![CDATA[ Vite.js es una herramienta veloz de desarrollo de proyectos web modernos. Se enfoca en la velocidad, el desempeño y mejora la experiencia del desarrollador. Vite usa las importaciones nativas ES (ECMA Script) del navegador para habilitar el soporte a navegadores modernos sin la necesidad de un proceso de compilación ("build ]]>
                </description>
                <link>https://www.freecodecamp.org/espanol/news/tutorial-vite-js-como-instalar-y-usar-vite-en-tus-proyectos-web/</link>
                <guid isPermaLink="false">662d57b47b1bd304018ef4ef</guid>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ vite ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Israel Palma ]]>
                </dc:creator>
                <pubDate>Wed, 15 May 2024 07:00:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/espanol/news/content/images/2024/04/getting-started-with-vite.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artículo original:</strong> <a href="https://www.freecodecamp.org/news/get-started-with-vite/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">Vite.js Tutorial – How to Install and Use Vite in Your Web Projects</a>
      </p><p>Vite.js es una herramienta veloz de desarrollo de proyectos web modernos. Se enfoca en la velocidad, el desempeño y mejora la experiencia del desarrollador.</p><p>Vite usa las importaciones nativas ES (ECMA Script) del navegador para habilitar el soporte a navegadores modernos sin la necesidad de un proceso de compilación ("build process").</p><p>Vite consta de dos partes principales:</p><ul><li>El servidor de desarrollo brinda soporte para la "sustitución de módulos en tiempo de ejecución" o bien, "Remplazo de Módulos en Caliente" (HMR - Hot Module Replacement, por sus siglas en inglés). De esta forma, cómo su nombre lo dice, actualiza los módulos de la aplicación en tiempo de ejecución. Así, que cuando se realizan cambios en el código, sólo se actualiza la parte editada, evitando recargar la aplicación completa, lo que ayuda a acortar el tiempo de desarrollo.</li><li>El comando "build" permite a los desarrolladores empaquetar su código con Rollup, que se encuentra pre-configurado para generar recursos estáticos (static assets) altamente optimizados para producción.</li></ul><h2 id="c-mo-funciona-vite-js"><strong>Cómo funciona Vite.js</strong></h2><p>Cuando se introdujeron los módulos ES en la versión ES6/ES2015, los navegadores no contaban con soporte para los módulos ES6 o bien, era el soporte era muy pobre. En la actualidad, los navegadores modernos ya brindan este soporte, lo que permite a los desarrolladores usar las declaraciones <code>import</code> y <code>export</code> de forma nativa.</p><p>En ES nativo, sin embargo, el <code>import</code> debe usar ya sea un URL relativo o absoluto ya que no es posible realizar "importaciones simples" (bare imports) de la forma:</p><pre><code class="language-js">import { algunMetodo } from 'mi-dependencia'</code></pre><p>El código anterior lanzará un error en el navegador pues no todos los navegadores tienen soporte para los módulos ES6, y usando ES6 sería necesario utilizar un "import map". Así que la cuestión ahora es, ¿cómo ayuda Vite con esto?</p><p>Vite detecta automáticamente las "importaciones simples" (bare imports) en tus archivos fuente y lleva a cabo las siguientes dos acciones:</p><ul><li>Vite pre-empaqueta los archivos fuente para acelerar la carga de la página y convierte los módulos CommonJS o UMD a módulos ESM.</li><li>Para permitirle a los navegadores importar módulos sin lanzar errores, Vite reescribirá las importaciones cómo URLs válidos como se muestra a continuación:</li></ul><pre><code>/node_modules/.vite/my-dep.js?v=f3sf2ebb</code></pre><h1 id="-por-qu-usar-vite"><strong>¿Por qué usar Vite?</strong></h1><p>Ahora que conocemos lo que es Vite y cómo funciona, te preguntarás por qué deberías usar Vite.</p><p>Hay varias razones por las cuales deberías usarlo en tus proyectos, veamos brevemente algunas de ellas.</p><h2 id="desempe-o"><strong>Desempeño</strong></h2><p>Pre-empaquetar con ESbuild de Vite es de 10 a 100 veces más rápido que otros empaquetadores JS (bundlers). Esto se debe a que al convertir los módulos CommonsJS o UMD a módulos ESM ayuda a mejorar la velocidad de carga.</p><p>De acuerdo con la documentación de Vite,</p><blockquote>"El paso de pre-empaquetado, se realiza con esbuild y hace que el tiempo de arranque en frío de Vite sea significativamente más rápido que cualquier empaquetador basado en JavaScript."</blockquote><h2 id="hot-module-replacement-hmr-"><strong>Hot Module Replacement (HMR)</strong></h2><p>Sustitución de Módulos en Tiempo de Ejecución.</p><p>Vite utiliza funcionalidades HMR para monitorear los cambios en tu aplicación, sin tener la necesidad de recargar la página completa. Con la API HMR, el navegador sólo cargará la sección modificada de la página y conservará el resto del estado de la aplicación. </p><p>No hay necesidad de configurar manualmente la API HMR en tu aplicación ya que es agregada a tu proyecto durante la instalación, si lo creaste mediante el uso de <a href="https://es.vitejs.dev/guide/">create-vite</a>.</p><p>Con el desempeño HMR puedes diseñar aplicaciones más rápidas y ligeras sin importar el número de módulos o el tamaño de tu aplicación.</p><h2 id="opciones-de-configuraci-n"><strong>Opciones de configuración</strong></h2><p>Vite permite que tengas más control de la configuración de tu proyecto al ampliar la configuración por defecto con <code>vite.config.js</code> o <code>vite.config.ts</code>. Estos archivos se encuentran en el directorio raíz de tu proyecto.</p><p>También puedes especificar distintos archivos de configuración con la opción CLI <code>--config</code> como se muestra abajo:</p><pre><code class="language-bash">vite --config my-config.js</code></pre><h1 id="lo-que-necesitar-s"><strong>Lo que necesitarás</strong></h1><p>Este es el software que debes tener instalado en tu computadora para poder crear un proyecto Vite:</p><ul><li><a href="https://nodejs.org/en/download/">Node.js versión 12.2.0</a> o superior (para ver la versión que tienes instalada en tu computadora ejecuta <strong><strong><code>node -v</code></strong></strong> en la terminal).</li><li><a href="https://www.npmjs.com/get-npm">Npm</a> / <a href="https://classic.yarnpkg.com/en/">Yarn</a></li></ul><p>Una vez que tengas estos programas instalados en tu computadora, podrás crear proyectos con Vite.</p><h1 id="c-mo-crear-un-proyecto-con-vite"><strong>Cómo crear un proyecto con Vite </strong></h1><p>Para crear una aplicación con Vite abre tu terminal o línea de comandos y navega hacia el directorio donde quieres guardar tu aplicación con Vite. Luego ejecuta el siguiente comando:</p><pre><code class="language-bash">npm create @vitejs/app my-vite-app</code></pre><p>O para versiones más recientes de Node:</p><pre><code class="language-bash">npm create vite@latest my-vite-app</code></pre><p><strong><strong>Note:</strong></strong> <strong><strong><code>my_vite_app</code></strong></strong> es el nombre de la aplicación con Vite que vamos a crear, pero puedes cambiarlo al nombre que tú prefieras. </p><p>Luego de ejecutar el comando de arriba, se te pedirá que selecciones un <code>framework</code> y una plantilla (<code>template</code> o variant). Para los propósitos de este tutorial, vamos a usar React, pero puedes elegir cualquier framework o variante con la que te sientas más familiarizado.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2022/04/v-edit-1.jpg" class="kg-image" alt="v-edit-1" width="600" height="400" loading="lazy"></figure><p>A continuación, ejecuta los siguientes comandos para finalizar la instalación:</p><pre><code class="language-bash">cd vite_application
npm install</code></pre><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2022/04/v-edit-1.png" class="kg-image" alt="v-edit-1" width="600" height="400" loading="lazy"></figure><p>La instalación puede tomar varios minutos, tendrás que esperar hasta que se haya completado.</p><h1 id="c-mo-ejecutar-una-aplicaci-n-con-vite"><strong>Cómo ejecutar una aplicación con Vite</strong></h1><p>Para ejecutar una aplicación con Vite en la terminal, navega al directorio de la aplicación que hemos creado <code>cd vite-aplication</code> y luego ejecuta el comando dev para ejecutar el servidor de desarrollo:</p><pre><code class="language-bash">npm run dev</code></pre><p>Ahora abre tu navegador e ingresa a <code><a href="http://localhost:3000/">http://localhost:3000</a></code>. Deberías ver algo como lo que muestra la siguiente captura:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2022/04/vite-4.PNG" class="kg-image" alt="vite-4" width="600" height="400" loading="lazy"><figcaption>Aplicación de React</figcaption></figure><h1 id="estructura-de-directorios-en-proyectos-con-vite"><strong>Estructura de directorios en proyectos con Vite</strong></h1><p>Veamos cómo es que están organizados los directorios en una aplicación con Vite. También daremos un vistazo en detalle a algunos de los directorios y archivos.</p><p>Nota: Si elijes usar un framework y/o plantilla distinto, el nombre de los archivos no será el mismo. <br></p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/espanol/news/content/images/2024/05/image.png" class="kg-image" alt="image" srcset="https://www.freecodecamp.org/espanol/news/content/images/size/w600/2024/05/image.png 600w, https://www.freecodecamp.org/espanol/news/content/images/size/w1000/2024/05/image.png 1000w, https://www.freecodecamp.org/espanol/news/content/images/size/w1600/2024/05/image.png 1600w, https://www.freecodecamp.org/espanol/news/content/images/2024/05/image.png 1659w" sizes="(min-width: 720px) 720px" width="1659" height="1280" loading="lazy"><figcaption>Estructura de directorios en aplicaciones con Vite</figcaption></figure><h3 id="el-directorio-node_modules"><strong>El directorio <strong><strong>node_modules </strong></strong></strong></h3><p>El directorio node_modules contiene todas las dependencias necesarias para la aplicación, que se encuentran especificadas en el archivo <code>package.json</code>.</p><p>Todas las dependencias configuradas en <code>package.json</code> serán descargadas al directorio node_modules una vez que hayamos ejecutado el comando <code>npm install</code>.</p><p>Al "empujar" (del inglés push) nuestro código fuente a GitHub no es necesario incluir el directorio node_modules ya que otros usuarios del código fuente pueden descargar las dependencias necesarias de la misma forma, es decir, gracias al archivo <code>package.json</code> y npm.</p><p>Puedes encontrar el archivo <code>package.json</code> en el directorio raíz de tu proyecto.</p><h3 id="el-directorio-src"><strong>El directorio <strong><strong>src</strong></strong></strong></h3><p>El directorio src es uno de los directorios con los que más vamos a interactuar al desarrollar aplicaciones con Vite. Este directorio contiene los archivos app.jsx, main.jsx, app.css e index.js.</p><p>Todos los recursos de tu aplicación como imágenes, videos y otros archivos deben estar dentro del directorio src ya que Vite lo considera como el directorio base para las URLs en index.html. &nbsp;</p><h3 id="los-archivos-app-jsx-y-main-jsx"><strong>Los archivos App.jsx y main.jsx</strong></h3><p>El archivo App.jsx es el componente base o raíz que hace la función de contenedor de todos los otros componentes utilizados en la aplicación.</p><p>El archivo main.jsx apunta al elemento con <code>id="root"</code> que se encuentra en el archivo index.html y en el cual se renderizan todos los componentes de la aplicación. </p><h3 id="index-css-y-app-css"><strong>index.css y app.css</strong></h3><p>Estos archivos contienen todos los estilos CSS que utiliza el programa. Puedes agregar tu propio archivo CSS o editar los estilos de index.css.</p><h1 id="conclusi-n"><strong>Conclusión</strong></h1><p>Hemos visto qué es Vite, cómo funciona y algunas de sus características. También aprendimos cómo crear aplicaciones usándolo. </p><p>Para modo de mejorar nuestro flujo de trabajo como desarrolladores y ser más productivos al crear aplicaciones más ligeras y veloces, es muy recomendable visitar, explorar, leer y familiarizarse con la documentación oficial de Vite. </p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ JavaScript Fetch API para principiantes: Explicado con ejemplos de código ]]>
                </title>
                <description>
                    <![CDATA[ Fetch API es una función de JavaScript que puede utilizar para enviar una solicitud a cualquier URL de API web y obtener una respuesta. En este artículo, le mostraré cómo realizar solicitudes HTTP a API externas utilizando la API Fetch de JavaScript. Aprenderá a crear solicitudes GET, POST, PUT/PATCH y ]]>
                </description>
                <link>https://www.freecodecamp.org/espanol/news/javascript-fetch-api-para-principiantes/</link>
                <guid isPermaLink="false">66305fb97b1bd304018ef79a</guid>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Cristian Fernando Villca Gutierrez ]]>
                </dc:creator>
                <pubDate>Tue, 07 May 2024 15:52:06 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/espanol/news/content/images/2024/04/javascript-fetch-cover-1.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-fetch-api-for-beginners/#how-to-send-a-post-request-using-the-fetch-api" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">JavaScript Fetch API For Beginners – Explained With Code Examples</a>
      </p><p>Fetch API es una función de JavaScript que puede utilizar para enviar una solicitud a cualquier URL de API web y obtener una respuesta.</p><p>En este artículo, le mostraré cómo realizar solicitudes HTTP a API externas utilizando la API Fetch de JavaScript. Aprenderá a crear solicitudes GET, POST, PUT/PATCH y DELETE utilizando la API Fetch.</p><p>Para aprovechar al máximo este artículo, debe tener un buen conocimiento de las promesas de JavaScript. Puedes leer mi artículo<a href="https://www.freecodecamp.org/news/javascript-promise-object-explained/"> Promesas en JavaScript</a> si necesitas un repaso.</p><ul><li><a href="#como">Cómo funciona la API Fetch</a></li><li><a href="#get">Cómo enviar una solicitud GET</a></li><li><a href="#post">Cómo enviar una solicitud POST</a></li><li><a href="#put">Cómo enviar una solicitud PUT</a></li><li><a href="#patch">Cómo enviar una solicitud PATCH</a></li><li><a href="#delete">Cómo enviar una solicitud DELETE</a></li><li><a href="#async-await">Cómo usar Async/Await con la API Fetch</a></li><li><a href="#ejemplos">Ejemplos de Código de Ejecución</a></li><li><a href="#resumen">Resumen</a></li></ul><p>¡Comencemos!</p><!--kg-card-begin: html--><h2 id="como">¿Cómo trabaja la API Fetch?</h2><!--kg-card-end: html--><p>Para enviar una petición similar a la de un formulario HTML, solo necesita pasar la URL donde desea enviar los datos como argumento a la función <code>fetch()</code>:</p><figure class="kg-card kg-code-card"><pre><code class="language-js">fetch('&lt;Tu URL&gt;', {})</code></pre><figcaption>Sintaxis de una petición Fetch</figcaption></figure><p>La función <code>fetch()</code> acepta dos parámetros:</p><ol><li>La URL a la que enviar la petición (este es un parámetro obligatorio).</li><li>Las opciones a configurar en la petición. Puede configurar el método de solicitud aquí (este es un parámetro opcional).</li></ol><p>Debajo del capó, la función <code>fetch()</code> devuelve una Promesa, por lo que necesitas agregar los métodos <code>.then()</code> y <code>.catch()</code>.</p><p>Cuando la petición devuelve una respuesta, se llamará al método <code>then()</code>. Si la solicitud devuelve un error, se ejecutará el método <code>catch()</code>:</p><figure class="kg-card kg-code-card"><pre><code class="language-js">fetch('&lt;Tu URL&gt;', {})
  .then(respuesta =&gt; {
    // Manejamos la respuesta de la petición aqui
  })
  .catch(error =&gt; {
    // Si hay un error en la petición, lo manejamos aqui 
  })</code></pre><figcaption>Respuesta de una solicitud Fetch con los métodos then() y catch()</figcaption></figure><p>Dentro de los métodos <code>.then()</code> y <code>.catch()</code>, pasas una función de callback de llamada para ejecutarla cuando se llaman los métodos respectivos.</p><p>El método <code>.catch()</code> se puede omitir en Fetch API. Se usa solo cuando Fetch no puede realizar una solicitud a la API, como por ejemplo si no hay conexión de red o no se encuentra la URL.</p><!--kg-card-begin: html--><h2 id="get">¿Cómo mandar una petición GET usando Fetch API?</h2><!--kg-card-end: html--><p>La petición GET es una solicitud HTTP que se utiliza para solicitar datos específicos de una API cuando así se necesita.</p><p>En el siguiente ejemplo, accederemos a una URL ficticia ubicada en <code>https://jsonplaceholder.typicode.com</code> para solicitar un usuario registrado en el sitio:</p><figure class="kg-card kg-code-card"><pre><code class="language-js">fetch('https://jsonplaceholder.typicode.com/users/1')
  .then(respuesta =&gt; console.log(respuesta))
  .catch(error =&gt; console.log(error));</code></pre><figcaption>Mandamos una petición GET usando Fetch API</figcaption></figure><p>El código anterior dará la siguiente respuesta:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/espanol/news/content/images/2024/04/fetch-readable-stream.png" class="kg-image" alt="fetch-readable-stream" srcset="https://www.freecodecamp.org/espanol/news/content/images/size/w600/2024/04/fetch-readable-stream.png 600w, https://www.freecodecamp.org/espanol/news/content/images/size/w1000/2024/04/fetch-readable-stream.png 1000w, https://www.freecodecamp.org/espanol/news/content/images/2024/04/fetch-readable-stream.png 1498w" sizes="(min-width: 720px) 720px" width="1498" height="608" loading="lazy"><figcaption>Respuesta de la petición HTTP</figcaption></figure><p>Aquí puede ver que la propiedad del cuerpo contiene un <code>ReadableStream</code>. Para usar <code>ReadableStream</code> en nuestra aplicación JavaScript, necesitamos convertirlo para llamar al método <code>json()</code>:</p><figure class="kg-card kg-code-card"><pre><code class="language-js">fetch('https://jsonplaceholder.typicode.com/users/1')
  .then(respuesta =&gt; respuesta.json())
  .then(datos =&gt; console.log(datos))</code></pre><figcaption>Convertir la respuesta a JSON usando el método json()</figcaption></figure><p>El método <code>json()</code> convierte <code>ReadableStream</code> en un objeto JavaScript. La variable de datos anterior se imprimirá de la siguiente manera:</p><figure class="kg-card kg-code-card"><pre><code class="language-js">{
  "id": 1,
  "name": "Leanne Graham",
  "username": "Bret",
  "email": "Sincere@april.biz",
  "address": {
    "street": "Kulas Light",
    "suite": "Apt. 556",
    "city": "Gwenborough",
    "zipcode": "92998-3874",
    "geo": {
      "lat": "-37.3159",
      "lng": "81.1496"
    }
  },
  "phone": "1-770-736-8031 x56442",
  "website": "hildegard.org",
  "company": {
    "name": "Romaguera-Crona",
    "catchPhrase": "Multi-layered client-server neural-net",
    "bs": "harness real-time e-markets"
  }
}</code></pre><figcaption>La petición regresa un objeto de JavaScript</figcaption></figure><p>Ahora que tiene el objeto de datos, puede utilizar este valor de la forma que desee. Por ejemplo, si desea mostrar el nombre de usuario y el correo electrónico en HTML, así es como lo hace:</p><figure class="kg-card kg-code-card"><pre><code class="language-html">&lt;body&gt;
  &lt;h1 id='nombre-usuario'&gt;Esperando por datos&lt;/h1&gt;
  &lt;h2 id='correo-usuario'&gt;Esperando por datos&lt;/h1&gt;
  &lt;script&gt;
    fetch('https://jsonplaceholder.typicode.com/users/1')
      .then(respuesta =&gt; respuesta.json())
      .then(datos =&gt; {
        document.querySelector('#nombre-usuario').textContent = datos.name
        document.querySelector('#correo-usuario').textContent = datos.email
      })
  &lt;/script&gt;
&lt;/body&gt;</code></pre><figcaption>Mostrnado datos de la petición Fetch en HTML</figcaption></figure><p>En el código anterior, la API Fetch se ejecutará tan pronto como el navegador cargue el documento HTML.</p><p>Después de procesar la respuesta en un objeto de datos, JavaScript cambiará el texto de los elementos <code>&lt;h1&gt;</code> y <code>&lt;h2&gt;</code> anteriores para reflejar el nombre y el correo electrónico del usuario.</p><p>Si ejecuta el código anterior, obtendrá el siguiente resultado:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/espanol/news/content/images/2024/04/fetch-get-response.png" class="kg-image" alt="fetch-get-response" srcset="https://www.freecodecamp.org/espanol/news/content/images/size/w600/2024/04/fetch-get-response.png 600w, https://www.freecodecamp.org/espanol/news/content/images/size/w1000/2024/04/fetch-get-response.png 1000w, https://www.freecodecamp.org/espanol/news/content/images/2024/04/fetch-get-response.png 1542w" sizes="(min-width: 720px) 720px" width="1542" height="1194" loading="lazy"><figcaption>Salida de la petición Fetch en el navegador</figcaption></figure><p>Y así es como envía una solicitud GET usando Fetch y muestra los datos devueltos en HTML.</p><p>Tenga en cuenta que, según la petición que solicite, una API puede devolver un tipo diferente de datos.</p><p>En este ejemplo, la API typicode devuelve un objeto, pero también puede obtener una matriz cuando solicita más de una unidad de datos.</p><p>Si accede a la URL en <a href="https://jsonplaceholder.typicode.com/users">https://jsonplaceholder.typicode.com/users</a>, verá que la API responde con un arreglo de objetos.</p><p>Necesita conocer el tipo de datos devuelto por la API para manejarlo correctamente.</p><!--kg-card-begin: html--><h2 id="post">¿Cómo mandar peticiones POST usando Fetch API?</h2><!--kg-card-end: html--><p>Si desea enviar una solicitud POST en lugar de una solicitud GET, debe definir el segundo argumento al llamar a la función, que es el objeto de configuración</p><p>Dentro del objeto de configuración, defina una propiedad <code>method</code> de la siguiente manera:</p><figure class="kg-card kg-code-card"><pre><code class="language-js">fetch('https://jsonplaceholder.typicode.com/users', {
  method: 'POST', // Establecemos el método de la petición aqui
})
.then(respuesta =&gt; respuesta.json())
.then(datos =&gt; console.log(datos))</code></pre><figcaption>Configuramos la petición Fetch con el método POST</figcaption></figure><p>Cuando envía un método POST, debe configurar el encabezado de la solicitud y las propiedades del cuerpo para garantizar un proceso fluido.</p><p>Para el encabezado, debe agregar la propiedad <code>Content-Type</code> y configurarla en <code>application/json</code>.</p><p>Los datos que desea enviar deben colocarse dentro de la propiedad `body` en formato JSON. Vea el ejemplo a continuación:</p><figure class="kg-card kg-code-card"><pre><code class="language-js">fetch('https://jsonplaceholder.typicode.com/users', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    nombre: 'Nathan Sebhastian',
    correo: 'ns@mail.com'
  }),
}).then(respuesta =&gt; respuesta.json())
  .then(datos =&gt; console.log(datos))</code></pre><figcaption>Agregamos a la petición la cabecera y el cuerpo&nbsp;</figcaption></figure><p>En el ejemplo anterior, enviamos una solicitud POST para crear un nuevo usuario. En la propiedad del cuerpo, un objeto JavaScript normal se convirtió en una cadena JSON llamando al método <code>JSON.stringify()</code>.</p><p>JSON es uno de los formatos que utilizan las computadoras para comunicarse entre sí en Internet.</p><p>La respuesta de la API de Typicode.com sería similar a la siguiente:</p><figure class="kg-card kg-code-card"><pre><code class="language-js">{
  "nombre": "Nathan Sebhastian",
  "correo": "ns@mail.com",
  "id": 11
}</code></pre><figcaption>Respuesta a la petición POST</figcaption></figure><p>Esto significa que creamos exitosamente un nuevo usuario. Dado que typicode.com es una API falsa, el usuario realmente no será agregado, pero simulará como si lo fuera.</p><!--kg-card-begin: html--><h2 id="put">¿Cómo mandar peticiones PUT?</h2><!--kg-card-end: html--><p>Una solicitud PUT se utiliza para crear un nuevo recurso o actualizar uno existente.</p><p>Por ejemplo, si desea actualizar un nombre de usuario y datos de correo electrónico existentes. Puede utilizar una solicitud PUT para hacerlo:</p><figure class="kg-card kg-code-card"><pre><code class="language-js">fetch('https://jsonplaceholder.typicode.com/users/1', {
  method: 'PUT',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    nombre: 'Nathan Sebhastian',
    correo: 'nathan@mail.com'
  }),
}).then(respuesta =&gt; resporespuestanse.json())
  .then(datos =&gt; console.log(datos))</code></pre><figcaption>Ejemplo de petición PUT usando Fetch API</figcaption></figure><p>La solicitud anterior recibirá la siguiente respuesta:</p><pre><code class="language-js">{
    "name": "Nathan Sebhastian",
    "email": "nathan@mail.com",
    "id": 1
}</code></pre><p>Debido a que ya existen datos de usuario con un <code>id</code> de 1, la solicitud PUT anterior actualiza esos datos.</p><p>A continuación, veamos la solicitud PATCH.</p><!--kg-card-begin: html--><h2 id="patch">¿Cómo mandar una petición PATCH?</h2><!--kg-card-end: html--><p>La solicitud PATCH se envía cuando necesita actualizar una petición existente.</p><p>Por ejemplo, si desea cambiar el <code>nombre</code> y el <code>usuario</code> de un usuario existente.</p><p>A continuación se muestra un ejemplo de cómo enviar una solicitud PATCH a typicode.com:</p><figure class="kg-card kg-code-card"><pre><code class="language-js">fetch('https://jsonplaceholder.typicode.com/users/1', {
  method: 'PATCH',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({ 
    nombre: 'Nathan Sebhastian',
    usaurio: 'nsebhastian'
  }),
}).then(respuesta =&gt; respuesta.json())
  .then(datos =&gt; console.log(datos))</code></pre><figcaption>Ejemplo de envio de una petición PATCH con Fetch API</figcaption></figure><p>La solicitud anterior recibirá la siguiente respuesta:</p><pre><code class="language-js">{
    "id": 1,
    "nombre": "Nathan Sebhastian",
    "usuario": "nsebhastian",
    "correo": "Sincere@april.biz",
    // ... the rest of user data
}</code></pre><p>Arriba, puede ver que los valores de las propiedades de <code>nombre</code> y<code>usuario</code> se actualizan utilizando el cuerpo de la solicitud PATCH.</p><!--kg-card-begin: html--><h2 id="delete">¿Cómo mandar una petición DELETE?</h2><!--kg-card-end: html--><p>La solicitud DELETE se utiliza cuando desea solicitar que un recurso se elimine permanentemente del servidor.</p><p>Para ejecutar una solicitud DELETE con Fetch, solo necesita especificar la URL del recurso que desea eliminar y el <code>method: 'DELETE'</code> de la siguiente manera:</p><figure class="kg-card kg-code-card"><pre><code class="language-js">fetch('https://jsonplaceholder.typicode.com/users/1', {
  method: 'DELETE',
}).then(respuesta =&gt; respuesta.json())
  .then(datos =&gt; console.log(datos))</code></pre><figcaption>Ejemplo de petición DELETE usando Fetch</figcaption></figure><p>La solicitud anterior eliminará los datos de un usuario que tenga un <code>id</code>de 1.</p><p>La API podría responder con algún mensaje para confirmar que el recurso se ha eliminado. Pero como typicode.com es una API ficticia, devolverá un objeto JavaScript vacío <code>{}</code>.</p><!--kg-card-begin: html--><h2 id="async-await">¿Cómo utilizar Async/Await con la API Fetch?</h2><!--kg-card-end: html--><p>Dado que Fetch devuelve un objeto <code>Promise</code>, esto significa que también puede usar la sintaxis <code>async/await</code> para reemplazar los métodos <code>.then()</code> y <code>.catch()</code>.</p><p>A continuación se muestra un ejemplo de envío de una solicitud GET usando Fetch en sintaxis async/await:</p><figure class="kg-card kg-code-card"><pre><code class="language-js">try {
  const respuesta = await fetch('https://jsonplaceholder.typicode.com/users/1');
  const json = await respuesta.json();
  console.log(json);
} catch (error) {
  console.log(error);
}</code></pre><figcaption>Usamos async/await para manejar la respuesta Fetch</figcaption></figure><p>Manejar una respuesta Fetch usando <code>async/await</code> parece más limpio porque no es necesario usar las devoluciones de llamada <code>.then()</code> y <code>.catch()</code>.</p><p>Si necesita un repaso sobre async/await, puede leer mi artículo <a href="https://www.freecodecamp.org/news/javascript-async-await/">JavaScript Async/Await</a>.</p><!--kg-card-begin: html--><h2 id="ejemplos">Ejecutando el código de ejemplo</h2><!--kg-card-end: html--><p>También creé un sitio web de ejemplo que le muestra cómo ejecutar estos 5 protocolos de solicitud HTTP en <a href="https://nathansebhastian.github.io/js-fetch-api/">https://nathansebhastian.github.io/js-fetch-api/</a></p><p>Compruébelo y estudie el objeto de datos devuelto. Para saber qué peticiones puede enviar a una API específica, debe consultar la documentación de ese proyecto de API.</p><!--kg-card-begin: html--><h2 id="resumen">Resumen</h2><!--kg-card-end: html--><p>Fetch API le permite acceder a las API y realizar una solicitud de red utilizando métodos de solicitud estándar como GET, POST, PUT, PATCH y DELETE.</p><p>La API Fetch devuelve una promesa, por lo que debe encadenar la llamada a la función con los métodos <code>.then()</code> y <code>.catch()</code>, o usar la sintaxis async/await.</p><p>¡Y así es como funciona la API Fetch! Si te ha gustado este artículo, quizás quieras consultar mi libro <a href="https://www.amazon.com/dp/B0CQXHMF8G?maas=maas_adg_8249349D07643FE6BFD0B487A55E6033_afap_abs&amp;ref_=aa_maas">Beginning Modern JavaScript</a> para mejorar tus habilidades en JavaScript:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/espanol/news/content/images/2024/05/beginning-js-cover.png" class="kg-image" alt="beginning-js-cover" srcset="https://www.freecodecamp.org/espanol/news/content/images/size/w600/2024/05/beginning-js-cover.png 600w, https://www.freecodecamp.org/espanol/news/content/images/size/w1000/2024/05/beginning-js-cover.png 1000w, https://www.freecodecamp.org/espanol/news/content/images/size/w1600/2024/05/beginning-js-cover.png 1600w, https://www.freecodecamp.org/espanol/news/content/images/2024/05/beginning-js-cover.png 2000w" sizes="(min-width: 720px) 720px" width="2000" height="1667" loading="lazy"></figure><p>El libro está diseñado para ser fácil para principiantes y accesible para cualquiera que quiera aprender JavaScript. Proporciona una guía sencilla paso a paso que le ayudará a comprender cómo utilizar JavaScript para crear una aplicación web dinámica.</p><p>Esta es mi promesa: realmente sentirás que entiendes lo que estás haciendo con JavaScript.</p><p>¡Nos vemos en otros artículos!</p> ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
