<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Cristian Arieta</title>
    <description>The latest articles on DEV Community by Cristian Arieta (@cristian_arieta_7df932e5f).</description>
    <link>https://dev.to/cristian_arieta_7df932e5f</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2704814%2Fee714422-5de3-4c4b-a293-63fee40dd49e.jpg</url>
      <title>DEV Community: Cristian Arieta</title>
      <link>https://dev.to/cristian_arieta_7df932e5f</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/cristian_arieta_7df932e5f"/>
    <language>en</language>
    <item>
      <title>Angular Pipes: Transformando Datos Directamente en tus Plantillas HTML 🔧 - Guía Exhaustiva ✨</title>
      <dc:creator>Cristian Arieta</dc:creator>
      <pubDate>Sat, 05 Apr 2025 17:54:55 +0000</pubDate>
      <link>https://dev.to/cristian_arieta_7df932e5f/angular-pipes-transformando-datos-directamente-en-tus-plantillas-html-guia-exhaustiva-56e6</link>
      <guid>https://dev.to/cristian_arieta_7df932e5f/angular-pipes-transformando-datos-directamente-en-tus-plantillas-html-guia-exhaustiva-56e6</guid>
      <description>&lt;p&gt;&lt;strong&gt;1. Introducción y Objetivos de Aprendizaje:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;¡Hola, desarrolladores! 👋 Hoy nos sumergiremos en una de las características más elegantes de Angular: los &lt;strong&gt;Pipes&lt;/strong&gt; 💧. Imaginen que tienen datos crudos en su componente (una fecha 📅, un número #️⃣, un texto largo 📜), pero necesitan mostrarlos en la plantilla HTML con un formato específico (fecha corta, moneda 💰, texto abreviado). Los Pipes son los "transformadores" 🪄 que nos permiten hacer esto directamente en el HTML, de forma limpia y reutilizable.&lt;/li&gt;
&lt;li&gt;Desde una perspectiva de arquitectura de software 🏗️, los Pipes son cruciales para adherirse al principio de &lt;strong&gt;Separación de Responsabilidades&lt;/strong&gt;. La lógica de &lt;em&gt;cómo&lt;/em&gt; mostrar los datos (formateo) pertenece a la capa de presentación (la plantilla), no necesariamente a la lógica de negocio del componente. Los Pipes encapsulan esta lógica de transformación ⚙️, haciéndola testeable ✅, reutilizable 🔄 y manteniendo los componentes más ligeros y enfocados en gestionar el estado y la interacción. Además, Angular optimiza el uso de Pipes (especialmente los "puros") para un rendimiento eficiente 🚀.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;(Nota de Repaso):&lt;/strong&gt; Al finalizar esta nota, usted podrá:

&lt;ul&gt;
&lt;li&gt;  ✅ Definir qué es un Pipe en Angular y cuál es su propósito principal.&lt;/li&gt;
&lt;li&gt;  ✅ Identificar y utilizar los Pipes incorporados (built-in) más comunes de Angular.&lt;/li&gt;
&lt;li&gt;  ✅ Comprender cómo pasar argumentos a los Pipes para personalizar la transformación.&lt;/li&gt;
&lt;li&gt;  ✅ Encadenar múltiples Pipes para aplicar varias transformaciones secuencialmente.&lt;/li&gt;
&lt;li&gt;  ✅ Crear y utilizar sus propios Pipes personalizados (Custom Pipes).&lt;/li&gt;
&lt;li&gt;  ✅ Distinguir entre Pipes Puros e Impuros y entender sus implicaciones de rendimiento.&lt;/li&gt;
&lt;li&gt;  ✅ Aplicar Pipes correctamente en las plantillas HTML de Angular usando la sintaxis &lt;code&gt;|&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;2. Conceptos Fundamentales (Definiciones Clave):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Pipe 🔧:&lt;/strong&gt; Una clase decorada con &lt;code&gt;@Pipe&lt;/code&gt; que implementa la interfaz &lt;code&gt;PipeTransform&lt;/code&gt;. Su función principal es &lt;strong&gt;transformar un valor de entrada en un valor de salida formateado&lt;/strong&gt; para ser mostrado en una plantilla HTML.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Transformación 🔄:&lt;/strong&gt; El proceso de convertir datos de un formato a otro (ej: objeto &lt;code&gt;Date&lt;/code&gt; a string &lt;code&gt;dd/MM/yyyy&lt;/code&gt;, número &lt;code&gt;1234.56&lt;/code&gt; a string &lt;code&gt;$1,234.56&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;&lt;code&gt;PipeTransform&lt;/code&gt; (Interfaz) 📝:&lt;/strong&gt; Interfaz que debe implementar toda clase Pipe. Define un único método obligatorio: &lt;code&gt;transform&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;&lt;code&gt;transform(value: any, ...args: any[]): any&lt;/code&gt; (Método) ✨:&lt;/strong&gt; El corazón del Pipe. Recibe el valor original (&lt;code&gt;value&lt;/code&gt;) que fluye desde la izquierda del operador &lt;code&gt;|&lt;/code&gt; en la plantilla, y opcionalmente, argumentos adicionales (&lt;code&gt;args&lt;/code&gt;) pasados después de dos puntos (&lt;code&gt;:&lt;/code&gt;). Debe devolver el valor transformado.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Sintaxis en Plantilla (&lt;code&gt;➡️ |&lt;/code&gt;):&lt;/strong&gt; El operador "pipe" se usa en las expresiones de interpolación (&lt;code&gt;{{ }}&lt;/code&gt;) o en los data bindings (&lt;code&gt;[property]="expression | pipe"&lt;/code&gt;) para aplicar un Pipe. &lt;code&gt;{{ valor | nombreDelPipe }}&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Argumentos de Pipe (&lt;code&gt;➡️ :&lt;/code&gt;):&lt;/strong&gt; Se pasan argumentos adicionales al método &lt;code&gt;transform&lt;/code&gt; usando dos puntos después del nombre del Pipe. &lt;code&gt;{{ valor | nombreDelPipe:arg1:arg2 }}&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Encadenamiento de Pipes ⛓️:&lt;/strong&gt; Aplicar múltiples Pipes secuencialmente. La salida de un Pipe se convierte en la entrada del siguiente. &lt;code&gt;{{ valor | pipe1 | pipe2:arg1 }}&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;3. Desarrollo del Tema: El Poder de los Pipes en Acción 🛠️&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Piensen en los datos fluyendo a través de "tuberías" (pipes) en su plantilla 💧➡️💧➡️🖥️. Cada tubería toma el dato, le hace algo (lo formatea, lo filtra, lo modifica) y lo pasa al siguiente, o finalmente lo muestra en la pantalla.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Profundicemos en los detalles técnicos y casos de uso:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A. ¿Por qué usar Pipes?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  ✅ &lt;strong&gt;Legibilidad del Template:&lt;/strong&gt; Mantiene las expresiones en HTML limpias. &lt;code&gt;{{ fechaCumpleanos | date:'shortDate' }}&lt;/code&gt; vs &lt;code&gt;{{ formatearFechaCorta(fechaCumpleanos) }}&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  ✅ &lt;strong&gt;Reutilización:&lt;/strong&gt; La lógica de formato es reutilizable en toda la app.&lt;/li&gt;
&lt;li&gt;  ✅ &lt;strong&gt;Separación de Responsabilidades:&lt;/strong&gt; Componente (qué datos) vs Pipe (cómo mostrarlos).&lt;/li&gt;
&lt;li&gt;  ✅ &lt;strong&gt;Performance (Pipes Puros):&lt;/strong&gt; Angular optimiza su ejecución 🚀.&lt;/li&gt;
&lt;li&gt;  ✅ &lt;strong&gt;Testabilidad:&lt;/strong&gt; Fáciles de probar unitariamente 🧪.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;B. Cómo Llamar Pipes desde HTML 💻:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Sintaxis Básica:&lt;/strong&gt; &lt;code&gt;{{ expresionAngular | nombrePipe }}&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;{{ titulo | uppercase }}&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt; &lt;span class="c"&gt;&amp;lt;!-- Muestra: HOLA MUNDO --&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Con Argumentos ⚙️:&lt;/strong&gt; &lt;code&gt;{{ expresionAngular | nombrePipe:argumento1:argumento2:... }}&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;Fecha: {{ fechaActual | date:'dd/MM/yyyy' }}&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt; &lt;span class="c"&gt;&amp;lt;!-- Ej: 15/06/2024 --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;Número: {{ numeroGrande | number:'1.2-2' }}&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt; &lt;span class="c"&gt;&amp;lt;!-- Muestra: 12,345.68 --&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Encadenamiento ⛓️:&lt;/strong&gt; &lt;code&gt;{{ expresionAngular | pipe1 | pipe2:argPipe2 | pipe3 }}&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;{{ descripcionLarga | slice:0:15 | uppercase }}...&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt; &lt;span class="c"&gt;&amp;lt;!-- Muestra: ESTE ES UN TEXT... --&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;C. Pipes Incorporados (Built-in) Más Comunes:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  📅 &lt;strong&gt;&lt;code&gt;DatePipe&lt;/code&gt;:&lt;/strong&gt; Formatea fechas. &lt;code&gt;{{ miFecha | date:'medium' }}&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  🅰️ &lt;strong&gt;&lt;code&gt;UpperCasePipe&lt;/code&gt;:&lt;/strong&gt; Convierte texto a MAYÚSCULAS. &lt;code&gt;{{ texto | uppercase }}&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  🔡 &lt;strong&gt;&lt;code&gt;LowerCasePipe&lt;/code&gt;:&lt;/strong&gt; Convierte texto a minúsculas. &lt;code&gt;{{ texto | lowercase }}&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  📖 &lt;strong&gt;&lt;code&gt;TitleCasePipe&lt;/code&gt;:&lt;/strong&gt; Convierte texto a Formato Título. &lt;code&gt;{{ texto | titlecase }}&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  #️⃣ &lt;strong&gt;&lt;code&gt;DecimalPipe&lt;/code&gt; (&lt;code&gt;number&lt;/code&gt;):&lt;/strong&gt; Formatea números. &lt;code&gt;{{ numero | number:'1.0-2' }}&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  % &lt;strong&gt;&lt;code&gt;PercentPipe&lt;/code&gt;:&lt;/strong&gt; Formatea números como porcentajes. &lt;code&gt;{{ 0.25 | percent }}&lt;/code&gt; (25%).&lt;/li&gt;
&lt;li&gt;  💰 &lt;strong&gt;&lt;code&gt;CurrencyPipe&lt;/code&gt;:&lt;/strong&gt; Formatea números como moneda. &lt;code&gt;{{ precio | currency:'USD':'symbol' }}&lt;/code&gt; ($1,234.56).&lt;/li&gt;
&lt;li&gt;  {} &lt;strong&gt;&lt;code&gt;JsonPipe&lt;/code&gt;:&lt;/strong&gt; Convierte objeto/array a JSON string (ideal para debug). &lt;code&gt;{{ miObjeto | json }}&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  ✂️ &lt;strong&gt;&lt;code&gt;SlicePipe&lt;/code&gt;:&lt;/strong&gt; Extrae sub-sección de array/string. &lt;code&gt;{{ miArray | slice:1:3 }}&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  🔑 &lt;strong&gt;&lt;code&gt;KeyValuePipe&lt;/code&gt;:&lt;/strong&gt; Itera sobre objetos/Maps en &lt;code&gt;*ngFor&lt;/code&gt;. &lt;code&gt;*ngFor="let item of miObjeto | keyvalue"&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  ⏳/⚡️ &lt;strong&gt;&lt;code&gt;AsyncPipe&lt;/code&gt;:&lt;/strong&gt; Se suscribe/desuscribe a Observables/Promises. &lt;code&gt;{{ miObservable$ | async }}&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;D. Creando Pipes Personalizados (Custom Pipes) 🔧:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;Generación (CLI) ⌨️:&lt;/strong&gt; &lt;code&gt;ng generate pipe nombre-del-pipe&lt;/code&gt; (ej: &lt;code&gt;ng g p truncate&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Implementación ✍️:&lt;/strong&gt; Edita &lt;code&gt;nombre-del-pipe.pipe.ts&lt;/code&gt;, implementa &lt;code&gt;transform()&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Ejemplo: truncate.pipe.ts&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Pipe&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;PipeTransform&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@angular/core&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Pipe&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;truncate&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;standalone&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;TruncatePipe&lt;/span&gt; &lt;span class="k"&gt;implements&lt;/span&gt; &lt;span class="nx"&gt;PipeTransform&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;limit&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;trail&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;...&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// ... (lógica de truncar) ...&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;limit&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;substring&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;limit&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;trail&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;

&lt;/ul&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    3.  Registro ✅:
        * Standalone Components: Importa en `imports: [..., TruncatePipe]`.
        * NgModules: Declara en `declarations: [...]`.
    4. Uso en Plantilla 💻: `{{ miTexto | truncate:100:' -&amp;gt;' }}`.

   Pipes Puros vs. Impuros:**
    * Pipes Puros 💧 (`pure: true` - por defecto):
        * Se ejecutan solo con cambios *puros* (primitivos o referencia de objeto).
        * Ventaja: Muy eficientes 🚀.
    * Pipes Impuros 🔥 (`pure: false`):
        * Se ejecutan en *cada* ciclo de detección de cambios.
        * Uso: Necesarios para cambios internos de objetos/arrays (sin cambio de referencia) o estado interno (ej: `AsyncPipe`, `JsonPipe`).
         Precaución: ⚠️ ¡Pueden impactar el rendimiento! Usar con moderación.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;4. Ejemplo Completo 🧪:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// en tu componente.ts&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@angular/core&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;CommonModule&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@angular/common&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Para pipes built-in&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;TruncatePipe&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./truncate.pipe&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Custom pipe&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Observable&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;interval&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;rxjs&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;map&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;rxjs/operators&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;app-pipe-demo&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;standalone&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;imports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;CommonModule&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;TruncatePipe&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="c1"&gt;// &amp;lt;-- Importados aquí&lt;/span&gt;
  &lt;span class="na"&gt;template&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`
    &amp;lt;h2&amp;gt;Demostración de Pipes 🧪&amp;lt;/h2&amp;gt;

    &amp;lt;p&amp;gt;📅 Fecha actual (completa): {{ ahora | date:'fullDate' }}&amp;lt;/p&amp;gt;
    &amp;lt;p&amp;gt;📅 Fecha actual (corta): {{ ahora | date:'short' }}&amp;lt;/p&amp;gt;

    &amp;lt;p&amp;gt;📖 Título Original: {{ libro.titulo }}&amp;lt;/p&amp;gt;
    &amp;lt;p&amp;gt;🅰️ Título en Mayúsculas: {{ libro.titulo | uppercase }}&amp;lt;/p&amp;gt;
    &amp;lt;p&amp;gt;✂️ Título Truncado: {{ libro.titulo | truncate:15:'...' }}&amp;lt;/p&amp;gt; &amp;lt;!-- Custom pipe --&amp;gt;

    &amp;lt;p&amp;gt;💰 Precio: {{ libro.precio | currency:'EUR':'symbol':'1.2-2' }}&amp;lt;/p&amp;gt;
    &amp;lt;p&amp;gt;% Descuento: {{ libro.descuento | percent:'1.0-0' }}&amp;lt;/p&amp;gt;

    &amp;lt;p&amp;gt;{} Descripción (JSON Debug):&amp;lt;/p&amp;gt;
    &amp;lt;pre&amp;gt;{{ libro | json }}&amp;lt;/pre&amp;gt;

    &amp;lt;p&amp;gt;✂️ Tags (Primeros 2):&amp;lt;/p&amp;gt;
    &amp;lt;ul&amp;gt;
      &amp;lt;li *ngFor="let tag of libro.tags | slice:0:2"&amp;gt;{{ tag | titlecase }}&amp;lt;/li&amp;gt;
    &amp;lt;/ul&amp;gt;

    &amp;lt;p&amp;gt;⏳ Contador (Async Pipe): {{ contador$ | async }}&amp;lt;/p&amp;gt;
  `&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PipeDemoComponent&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;ahora&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="nx"&gt;libro&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="cm"&gt;/* ... datos del libro ... */&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="nx"&gt;contador$&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Observable&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;interval&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;pipe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;5. Buenas Prácticas y Consideraciones Adicionales 👍:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;*&lt;br&gt;
    *   ✨ &lt;strong&gt;Prioriza Pipes Puros:&lt;/strong&gt; Mejor rendimiento.&lt;br&gt;
    *   ✨ &lt;strong&gt;Evita Lógica Compleja en Pipes:&lt;/strong&gt; Mantenlos simples y enfocados.&lt;br&gt;
    *   ✨ &lt;strong&gt;Reutilización:&lt;/strong&gt; Crea Custom Pipes para lógica repetida.&lt;br&gt;
    *   ✨ &lt;strong&gt;No Abuses del Encadenamiento:&lt;/strong&gt; Puede reducir legibilidad.&lt;br&gt;
    *   ✨ &lt;strong&gt;Cuidado con Pipes Impuros y &lt;code&gt;*ngFor&lt;/code&gt;:&lt;/strong&gt; Considera &lt;code&gt;trackBy&lt;/code&gt;.&lt;br&gt;
    *   🌐 &lt;strong&gt;Internacionalización (i18n):&lt;/strong&gt; Configura &lt;code&gt;LOCALE_ID&lt;/code&gt; para &lt;code&gt;DatePipe&lt;/code&gt;, &lt;code&gt;CurrencyPipe&lt;/code&gt;, etc.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;👨‍🏫 ¡Revisa los Pipes built-in antes de crear uno! ¡Y prueba tus creaciones! 🧪&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;6. Resumen / Puntos Clave para el Repaso 📌:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  ✅ &lt;strong&gt;Pipes:&lt;/strong&gt; Transforman datos en plantillas (&lt;code&gt;@Pipe&lt;/code&gt;, &lt;code&gt;PipeTransform&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;  ✅ &lt;strong&gt;Propósito:&lt;/strong&gt; Formateo, legibilidad, reutilización, separación.&lt;/li&gt;
&lt;li&gt;  ✅ &lt;strong&gt;Sintaxis:&lt;/strong&gt; &lt;code&gt;{{ valor | nombrePipe:arg1 }}&lt;/code&gt;. Encadenables (&lt;code&gt;| pipe1 | pipe2&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;  ✅ &lt;strong&gt;Built-in:&lt;/strong&gt; Date, Upper/Lower/TitleCase, number, Currency, Percent, Json, Slice, KeyValue, Async.&lt;/li&gt;
&lt;li&gt;  ✅ &lt;strong&gt;Custom Pipes:&lt;/strong&gt; &lt;code&gt;ng g p nombre&lt;/code&gt;, implementa &lt;code&gt;transform()&lt;/code&gt;, importa/declara.&lt;/li&gt;
&lt;li&gt;  ✅ &lt;strong&gt;Puros (💧) vs. Impuros (🔥):&lt;/strong&gt; Puros más eficientes, Impuros para casos específicos (¡cuidado!).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;7. Preguntas de Autoevaluación 🤔:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; ❓ ¿Cuál es el beneficio principal de usar Pipes sobre métodos de componente para formato?&lt;/li&gt;
&lt;li&gt; ❓ Sintaxis para &lt;code&gt;DatePipe&lt;/code&gt; con formato 'dd-MMM-yyyy'.&lt;/li&gt;
&lt;li&gt; ❓ ¿Qué significa "Pipe puro" y por qué importa?&lt;/li&gt;
&lt;li&gt; ❓ ¿Cuándo usarías &lt;code&gt;AsyncPipe&lt;/code&gt;?&lt;/li&gt;
&lt;li&gt; ❓ Pasos para crear un Pipe &lt;code&gt;addPrefix&lt;/code&gt; que añada "PRE:" a un string.&lt;/li&gt;
&lt;/ol&gt;




</description>
      <category>angular</category>
      <category>pipes</category>
      <category>typescript</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Expresiones Regulares (RegEx): Guía Esencial para Desarrolladores - Nota de Repaso</title>
      <dc:creator>Cristian Arieta</dc:creator>
      <pubDate>Sat, 05 Apr 2025 17:39:59 +0000</pubDate>
      <link>https://dev.to/cristian_arieta_7df932e5f/expresiones-regulares-regex-guia-esencial-para-desarrolladores-nota-de-repaso-1adb</link>
      <guid>https://dev.to/cristian_arieta_7df932e5f/expresiones-regulares-regex-guia-esencial-para-desarrolladores-nota-de-repaso-1adb</guid>
      <description>&lt;p&gt;&lt;strong&gt;1. Introducción y Objetivos de Aprendizaje:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;¡Bienvenidos al fascinante mundo de las Expresiones Regulares! Piensen en ellas como un "lenguaje" súper compacto y especializado para &lt;strong&gt;buscar, encontrar y manipular patrones dentro de texto&lt;/strong&gt;. Desde validar un correo electrónico hasta extraer datos específicos de archivos de log gigantescos, las RegEx son una habilidad fundamental en la caja de herramientas de cualquier desarrollador.&lt;/li&gt;
&lt;li&gt;En la práctica, las RegEx son indispensables. Son soportadas por casi todos los lenguajes de programación modernos y herramientas de línea de comandos. Dominarlas no solo ahorra incontables líneas de código manual para el procesamiento de cadenas, sino que también permite realizar tareas complejas de forma eficiente. Sin embargo, su sintaxis concisa puede ser críptica; la clave es entender sus componentes fundamentales y construir patrones paso a paso.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;(Nota de Repaso):&lt;/strong&gt; Al finalizar esta nota, usted podrá:

&lt;ul&gt;
&lt;li&gt;  Definir qué es una Expresión Regular y su propósito principal.&lt;/li&gt;
&lt;li&gt;  Identificar y comprender los metacaracteres y cuantificadores básicos.&lt;/li&gt;
&lt;li&gt;  Utilizar clases de caracteres y anclas para refinar búsquedas.&lt;/li&gt;
&lt;li&gt;  Construir patrones simples para validación y búsqueda en JavaScript.&lt;/li&gt;
&lt;li&gt;  Reconocer los casos de uso más comunes de las RegEx.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;2. Conceptos Fundamentales (Definiciones Clave):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Expresión Regular (RegEx / RegExp):&lt;/strong&gt; Una secuencia de caracteres que define un &lt;strong&gt;patrón de búsqueda&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Motor de RegEx:&lt;/strong&gt; El software que interpreta el patrón de RegEx y lo aplica sobre un texto (string) para encontrar coincidencias.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Literal:&lt;/strong&gt; Un carácter en la RegEx que se corresponde consigo mismo en el texto (ej: &lt;code&gt;a&lt;/code&gt; busca la letra 'a').&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Metacarácter:&lt;/strong&gt; Carácter con un &lt;strong&gt;significado especial&lt;/strong&gt; en el contexto de una RegEx (ej: &lt;code&gt;.&lt;/code&gt; que significa "cualquier carácter excepto nueva línea"). Necesitan ser "escapados" con una barra invertida (&lt;code&gt;\&lt;/code&gt;) si quieres buscar el carácter literal (ej: &lt;code&gt;\.&lt;/code&gt; busca un punto literal).&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Coincidencia (Match):&lt;/strong&gt; El fragmento de texto que cumple con el patrón definido por la RegEx.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Flags (Banderas):&lt;/strong&gt; Modificadores que cambian el comportamiento de la búsqueda (ej: &lt;code&gt;i&lt;/code&gt; para ignorar mayúsculas/minúsculas, &lt;code&gt;g&lt;/code&gt; para búsqueda global - encontrar todas las coincidencias, no solo la primera).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;3. Desarrollo del Tema: Construyendo Patrones RegEx&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Pensemos en construir una RegEx como armar una descripción muy precisa de lo que buscamos. Usamos bloques de construcción (caracteres y metacaracteres) para definir ese patrón.&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;La potencia reside en combinar estos elementos. Aquí los componentes esenciales:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Literales:&lt;/strong&gt; &lt;code&gt;abc&lt;/code&gt; busca la secuencia exacta "abc".&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Metacaracteres Comunes:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;code&gt;.&lt;/code&gt; (Punto): Cualquier carácter excepto salto de línea.&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;\&lt;/code&gt; (Barra invertida): Escapa un metacarácter para tratarlo como literal (&lt;code&gt;\.&lt;/code&gt;, &lt;code&gt;\*&lt;/code&gt;, &lt;code&gt;\?&lt;/code&gt;) o da significado especial a caracteres normales (&lt;code&gt;\d&lt;/code&gt;, &lt;code&gt;\s&lt;/code&gt;, &lt;code&gt;\w&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;|&lt;/code&gt; (Barra vertical / Pipe): Actúa como un "OR" lógico. &lt;code&gt;a|b&lt;/code&gt; busca 'a' o 'b'.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;  &lt;strong&gt;Clases de Caracteres &lt;code&gt;[...]&lt;/code&gt;:&lt;/strong&gt; Definen un conjunto de caracteres posibles.

&lt;ul&gt;
&lt;li&gt;  &lt;code&gt;[aeiou]&lt;/code&gt; : Busca cualquier vocal minúscula.&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;[a-zA-Z0-9]&lt;/code&gt; : Busca cualquier letra (mayúscula o minúscula) o dígito.&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;[^0-9]&lt;/code&gt; (con &lt;code&gt;^&lt;/code&gt; &lt;em&gt;dentro&lt;/em&gt; de corchetes): Busca cualquier carácter que &lt;strong&gt;NO&lt;/strong&gt; sea un dígito (clase negada).&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;  &lt;strong&gt;Clases Predefinidas (Atajos):&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;code&gt;\d&lt;/code&gt;: Cualquier dígito (equivalente a &lt;code&gt;[0-9]&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;\D&lt;/code&gt;: Cualquier carácter que NO sea un dígito (&lt;code&gt;[^0-9]&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;\w&lt;/code&gt;: Cualquier carácter de "palabra" (alfanumérico + guion bajo: &lt;code&gt;[a-zA-Z0-9_]&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;\W&lt;/code&gt;: Cualquier carácter que NO sea de palabra (&lt;code&gt;[^a-zA-Z0-9_]&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;\s&lt;/code&gt;: Cualquier carácter de espacio en blanco (espacio, tabulador, salto de línea, etc.).&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;\S&lt;/code&gt;: Cualquier carácter que NO sea espacio en blanco.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;  &lt;strong&gt;Cuantificadores (Repetición):&lt;/strong&gt; Se aplican al carácter o grupo &lt;em&gt;anterior&lt;/em&gt;.

&lt;ul&gt;
&lt;li&gt;  &lt;code&gt;*&lt;/code&gt;: Cero o más veces. &lt;code&gt;a*&lt;/code&gt; busca "", "a", "aa", "aaa", etc.&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;+&lt;/code&gt;: Una o más veces. &lt;code&gt;a+&lt;/code&gt; busca "a", "aa", "aaa", etc. (pero no "").&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;?&lt;/code&gt;: Cero o una vez (opcional). &lt;code&gt;colou?r&lt;/code&gt; busca "color" o "colour".&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;{n}&lt;/code&gt;: Exactamente &lt;code&gt;n&lt;/code&gt; veces. &lt;code&gt;\d{3}&lt;/code&gt; busca exactamente tres dígitos.&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;{n,}&lt;/code&gt;: Al menos &lt;code&gt;n&lt;/code&gt; veces. &lt;code&gt;\d{2,}&lt;/code&gt; busca dos o más dígitos.&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;{n,m}&lt;/code&gt;: Entre &lt;code&gt;n&lt;/code&gt; y &lt;code&gt;m&lt;/code&gt; veces (inclusive). &lt;code&gt;\d{2,4}&lt;/code&gt; busca de dos a cuatro dígitos.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Codiciosos (Greedy) vs. Perezosos (Lazy):&lt;/strong&gt; Por defecto, los cuantificadores son "codiciosos" (intentan abarcar lo máximo posible). Añadiendo &lt;code&gt;?&lt;/code&gt; después del cuantificador los vuelve "perezosos" (abarcan lo mínimo). &lt;code&gt;.*&lt;/code&gt; vs &lt;code&gt;.*?&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;  &lt;strong&gt;Anclas (Posición):&lt;/strong&gt; No buscan caracteres, sino posiciones en el texto.

&lt;ul&gt;
&lt;li&gt;  &lt;code&gt;^&lt;/code&gt;: Inicio de la cadena (o línea, con flag &lt;code&gt;m&lt;/code&gt;). &lt;code&gt;^abc&lt;/code&gt; busca "abc" solo si está al principio.&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;$&lt;/code&gt;: Fin de la cadena (o línea, con flag &lt;code&gt;m&lt;/code&gt;). &lt;code&gt;xyz$&lt;/code&gt; busca "xyz" solo si está al final.&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;\b&lt;/code&gt;: Límite de palabra (word boundary). Posición entre un &lt;code&gt;\w&lt;/code&gt; y un &lt;code&gt;\W&lt;/code&gt;, o inicio/fin de cadena si el primer/último carácter es &lt;code&gt;\w&lt;/code&gt;. &lt;code&gt;\bword\b&lt;/code&gt; busca la palabra "word" completa, no como parte de "swordfish".&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;\B&lt;/code&gt;: Posición que NO es un límite de palabra.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;  &lt;strong&gt;Grupos &lt;code&gt;(...)&lt;/code&gt;:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;  Agrupan partes del patrón: &lt;code&gt;(abc)+&lt;/code&gt; busca "abc", "abcabc", etc.&lt;/li&gt;
&lt;li&gt;  Capturan el texto coincidente: Permiten extraer sub-partes de la coincidencia total.&lt;/li&gt;
&lt;li&gt;  Grupo no capturador: &lt;code&gt;(?:...)&lt;/code&gt;. Agrupa pero no captura (más eficiente si no necesitas la captura).&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;/li&gt;

&lt;li&gt;&lt;p&gt;&lt;strong&gt;(Nota de Repaso):&lt;/strong&gt; La estructura básica es: &lt;code&gt;Caracteres&lt;/code&gt; + &lt;code&gt;Cuantificadores&lt;/code&gt; + &lt;code&gt;Anclas&lt;/code&gt;. Usa &lt;code&gt;[]&lt;/code&gt; para conjuntos, &lt;code&gt;()&lt;/code&gt; para agrupar/capturar, y &lt;code&gt;&amp;lt;/code&amp;gt; para escapar o usar clases predefinidas.&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;4. Ejemplo Práctico (Validación de Email Simple en JavaScript)&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Vamos a crear una RegEx para validar un formato de email muy básico. No será perfecta (la validación real de emails es muy compleja), pero ilustrará los conceptos. Queremos algo como: &lt;code&gt;nombre@dominio.ext&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Un patrón podría ser: &lt;code&gt;^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Patrón RegEx para una validación simple de email&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;emailRegex&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sr"&gt;/^&lt;/span&gt;&lt;span class="se"&gt;[&lt;/span&gt;&lt;span class="sr"&gt;a-zA-Z0-9._%+-&lt;/span&gt;&lt;span class="se"&gt;]&lt;/span&gt;&lt;span class="sr"&gt;+@&lt;/span&gt;&lt;span class="se"&gt;[&lt;/span&gt;&lt;span class="sr"&gt;a-zA-Z0-9.-&lt;/span&gt;&lt;span class="se"&gt;]&lt;/span&gt;&lt;span class="sr"&gt;+&lt;/span&gt;&lt;span class="se"&gt;\.[&lt;/span&gt;&lt;span class="sr"&gt;a-zA-Z&lt;/span&gt;&lt;span class="se"&gt;]{2,}&lt;/span&gt;&lt;span class="sr"&gt;$/&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Explicación del patrón:&lt;/span&gt;
&lt;span class="c1"&gt;// ^                     -&amp;gt; Inicio de la cadena&lt;/span&gt;
&lt;span class="c1"&gt;// [a-zA-Z0-9._%+-]+   -&amp;gt; Parte del nombre (antes del @):&lt;/span&gt;
&lt;span class="c1"&gt;//    [a-zA-Z0-9._%+-] -&amp;gt; Permite letras, números, y los caracteres ., _, %, +, -&lt;/span&gt;
&lt;span class="c1"&gt;//    +                 -&amp;gt; Debe haber uno o más de estos caracteres&lt;/span&gt;
&lt;span class="c1"&gt;// @                     -&amp;gt; El carácter literal '@'&lt;/span&gt;
&lt;span class="c1"&gt;// [a-zA-Z0-9.-]+      -&amp;gt; Parte del dominio (después del @, antes del último .):&lt;/span&gt;
&lt;span class="c1"&gt;//    [a-zA-Z0-9.-]    -&amp;gt; Permite letras, números, puntos y guiones&lt;/span&gt;
&lt;span class="c1"&gt;//    +                 -&amp;gt; Debe haber uno o más&lt;/span&gt;
&lt;span class="c1"&gt;// \.                    -&amp;gt; El carácter literal '.' (escapado porque '.' es metacarácter)&lt;/span&gt;
&lt;span class="c1"&gt;// [a-zA-Z]{2,}         -&amp;gt; Extensión del dominio (después del último .):&lt;/span&gt;
&lt;span class="c1"&gt;//    [a-zA-Z]          -&amp;gt; Solo letras&lt;/span&gt;
&lt;span class="c1"&gt;//    {2,}              -&amp;gt; Debe haber al menos 2 letras (ej: com, org, uk, io)&lt;/span&gt;
&lt;span class="c1"&gt;// $                     -&amp;gt; Fin de la cadena&lt;/span&gt;

&lt;span class="c1"&gt;// Cómo usarlo en JavaScript:&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;email1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;test.user+alias@example-domain.com&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;email2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;invalid-email@&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;email3&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;another@domain.c&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Extensión muy corta&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;email4&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt; user@domain.com&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Espacio al inicio&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`"&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;email1&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;" es válido? &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;emailRegex&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;email1&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// true&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`"&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;email2&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;" es válido? &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;emailRegex&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;email2&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// false&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`"&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;email3&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;" es válido? &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;emailRegex&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;email3&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// false&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`"&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;email4&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;" es válido? &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;emailRegex&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;email4&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// false (por el espacio y ^)&lt;/span&gt;

&lt;span class="c1"&gt;// Otros métodos útiles:&lt;/span&gt;
&lt;span class="c1"&gt;// const matchResult = email1.match(emailRegex); // Devuelve detalles de la coincidencia o null&lt;/span&gt;
&lt;span class="c1"&gt;// const replacedString = email1.replace(/@.*/, '@new-domain.net'); // Reemplazar partes&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;5. Buenas Prácticas y Consideraciones Adicionales:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;*&lt;br&gt;
    *   &lt;strong&gt;Especificidad:&lt;/strong&gt; Sé tan específico como sea posible. &lt;code&gt;.*&lt;/code&gt; es potente pero a menudo demasiado amplio y puede llevar a coincidencias inesperadas y problemas de rendimiento (backtracking catastrófico).&lt;br&gt;
    *   &lt;strong&gt;Legibilidad:&lt;/strong&gt; Las RegEx complejas son difíciles de leer. Coméntalas exhaustivamente o divídelas en partes más pequeñas si es posible. Usa el flag &lt;code&gt;x&lt;/code&gt; (comentarios y espacios en blanco ignorados) si tu motor lo soporta.&lt;br&gt;
    *   &lt;strong&gt;Testing:&lt;/strong&gt; Prueba tus RegEx con una variedad de casos válidos e inválidos. Usa herramientas online como Regex101, RegExr, o las herramientas de desarrollo de tu navegador.&lt;br&gt;
    *   &lt;strong&gt;Performance:&lt;/strong&gt; Sé consciente del backtracking. Patrones anidados con cuantificadores &lt;code&gt;*&lt;/code&gt; o &lt;code&gt;+&lt;/code&gt; pueden ser muy lentos en ciertos casos. Usa grupos no capturadores &lt;code&gt;(?:...)&lt;/code&gt; si no necesitas la captura.&lt;br&gt;
    *   &lt;strong&gt;Escapado:&lt;/strong&gt; Recuerda escapar los metacaracteres (&lt;code&gt;.&lt;/code&gt;, &lt;code&gt;?&lt;/code&gt;, &lt;code&gt;*&lt;/code&gt;, &lt;code&gt;+&lt;/code&gt;, &lt;code&gt;(&lt;/code&gt;, &lt;code&gt;)&lt;/code&gt;, &lt;code&gt;[&lt;/code&gt;, &lt;code&gt;]&lt;/code&gt;, &lt;code&gt;{&lt;/code&gt;, &lt;code&gt;}&lt;/code&gt;, &lt;code&gt;^&lt;/code&gt;, &lt;code&gt;$&lt;/code&gt;, &lt;code&gt;\&lt;/code&gt;, &lt;code&gt;|&lt;/code&gt;) si quieres buscar el carácter literal.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Empieza simple y añade complejidad gradualmente. No intentes crear el patrón perfecto de una sola vez. ¡La práctica y las herramientas de prueba son tus mejores aliados!&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;(Nota de Repaso):&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Do:&lt;/strong&gt; Testear, comentar, ser específico, escapar metacaracteres, empezar simple.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Don't:&lt;/strong&gt; Usar &lt;code&gt;.*&lt;/code&gt; sin cuidado, crear patrones innecesariamente complejos sin comentarios, olvidar las anclas &lt;code&gt;^&lt;/code&gt; y &lt;code&gt;$&lt;/code&gt; para validaciones completas de cadenas.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;6. Resumen / Puntos Clave para el Repaso:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;RegEx:&lt;/strong&gt; Patrones para buscar/manipular texto.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Bloques Básicos:&lt;/strong&gt; Literales, Metacaracteres (&lt;code&gt;.&lt;/code&gt; &lt;code&gt;\&lt;/code&gt; &lt;code&gt;|&lt;/code&gt;), Clases (&lt;code&gt;[]&lt;/code&gt; &lt;code&gt;\d&lt;/code&gt; &lt;code&gt;\w&lt;/code&gt; &lt;code&gt;\s&lt;/code&gt;), Cuantificadores (&lt;code&gt;*&lt;/code&gt; &lt;code&gt;+&lt;/code&gt; &lt;code&gt;?&lt;/code&gt; &lt;code&gt;{n,m}&lt;/code&gt;), Anclas (&lt;code&gt;^&lt;/code&gt; &lt;code&gt;$&lt;/code&gt; &lt;code&gt;\b&lt;/code&gt;), Grupos (&lt;code&gt;()&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Uso Común en JS:&lt;/strong&gt; &lt;code&gt;/patron/flags&lt;/code&gt;, método &lt;code&gt;.test()&lt;/code&gt;, &lt;code&gt;.match()&lt;/code&gt;, &lt;code&gt;.replace()&lt;/code&gt;, &lt;code&gt;.search()&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Flags Clave:&lt;/strong&gt; &lt;code&gt;i&lt;/code&gt; (insensible a mayús/minús), &lt;code&gt;g&lt;/code&gt; (global).&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Clave del Éxito:&lt;/strong&gt; ¡Práctica y Testing!&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;7. Preguntas de Autoevaluación:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; ¿Qué buscaría la expresión regular &lt;code&gt;/gato|perro/i&lt;/code&gt;?&lt;/li&gt;
&lt;li&gt; ¿Cuál es la diferencia entre &lt;code&gt;*&lt;/code&gt;, &lt;code&gt;+&lt;/code&gt; y &lt;code&gt;?&lt;/code&gt; como cuantificadores?&lt;/li&gt;
&lt;li&gt; ¿Para qué sirven las anclas &lt;code&gt;^&lt;/code&gt; y &lt;code&gt;$&lt;/code&gt; en una expresión regular utilizada para validar una entrada completa de usuario?&lt;/li&gt;
&lt;li&gt; ¿Cómo buscarías un punto literal (&lt;code&gt;.&lt;/code&gt;) en un texto usando RegEx?&lt;/li&gt;
&lt;/ol&gt;




&lt;p&gt;Espero que esta guía te resulte útil para entender y repasar las expresiones regulares.&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>angular</category>
      <category>javascript</category>
      <category>devops</category>
    </item>
    <item>
      <title>Funciones Recursivas en JavaScript: Modificando Datos Anidados por ID - Guía Práctica</title>
      <dc:creator>Cristian Arieta</dc:creator>
      <pubDate>Sat, 05 Apr 2025 17:27:35 +0000</pubDate>
      <link>https://dev.to/cristian_arieta_7df932e5f/funciones-recursivas-en-javascript-modificando-datos-anidados-por-id-guia-practica-1j4b</link>
      <guid>https://dev.to/cristian_arieta_7df932e5f/funciones-recursivas-en-javascript-modificando-datos-anidados-por-id-guia-practica-1j4b</guid>
      <description>&lt;p&gt;&lt;strong&gt;1. Introducción y Objetivos de Aprendizaje:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;(Nota de Repaso):&lt;/strong&gt; Al finalizar esta nota, usted podrá:

&lt;ul&gt;
&lt;li&gt;  Definir qué es una función recursiva y sus componentes (caso base, paso recursivo).&lt;/li&gt;
&lt;li&gt;  Identificar por qué la recursión es adecuada para estructuras de datos anidadas.&lt;/li&gt;
&lt;li&gt;  Implementar una función recursiva para buscar un elemento por ID en un objeto/array anidado.&lt;/li&gt;
&lt;li&gt;  Modificar un campo específico del elemento encontrado de forma inmutable (buenas prácticas).&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;2. Conceptos Fundamentales (Definiciones Clave):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Recursión:&lt;/strong&gt; Técnica de programación donde una función se llama a sí misma para resolver una versión más pequeña del problema original.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Caso Base:&lt;/strong&gt; Condición dentro de una función recursiva que &lt;strong&gt;detiene&lt;/strong&gt; las llamadas sucesivas a sí misma. Es crucial para evitar un desbordamiento de pila (stack overflow). Generalmente, representa el caso más simple del problema que se puede resolver directamente.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Paso Recursivo:&lt;/strong&gt; La parte de la función donde se &lt;strong&gt;llama a sí misma&lt;/strong&gt;, pero típicamente con datos modificados que se acercan al caso base.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Estructura de Datos Anidada:&lt;/strong&gt; Una colección de datos donde los elementos pueden contener otras colecciones (ej: un objeto con propiedades que son otros objetos o arrays, que a su vez pueden contener más).&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Inmutabilidad:&lt;/strong&gt; Práctica de no modificar los datos originales. En su lugar, se crean copias modificadas. Esto mejora la predictibilidad y facilita el debugging.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;3. Desarrollo del Tema: Navegación y Modificación Recursiva&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Imaginen que tenemos una caja que puede contener objetos o más cajas. Queremos encontrar un objeto específico (marcado con una etiqueta, nuestro ID) dentro de cualquier caja, sin importar cuán adentro esté, y cambiarle algo. La recursión nos permite "abrir" cada caja:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; ¿Es esta caja el objeto que busco? (Verificar ID). Si sí, ¡lo encontré! Lo modifico y termino. (Parte del Caso Base)&lt;/li&gt;
&lt;li&gt; ¿Esta caja está vacía o no contiene más cajas/objetos? Si sí, no hay nada más que hacer aquí. (Otro Caso Base)&lt;/li&gt;
&lt;li&gt; Si no es el objeto buscado y contiene más cosas (otras cajas/objetos), repito el proceso (llamo a la misma función) para cada una de las cosas que hay dentro. (Paso Recursivo)&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;El desafío técnico está en manejar correctamente los diferentes tipos de "contenedores" (principalmente objetos y arrays en JavaScript) y en cómo propagar la modificación hacia arriba una vez que se encuentra el elemento. Para la &lt;strong&gt;búsqueda&lt;/strong&gt;, iteramos sobre las propiedades de un objeto o los elementos de un array. Si el elemento actual coincide con el ID, realizamos la modificación. Si no, y si el elemento actual es a su vez un objeto o array, llamamos recursivamente a nuestra función sobre ese elemento. Es &lt;strong&gt;fundamental&lt;/strong&gt; manejar la inmutabilidad: en lugar de modificar el objeto/array original, creamos uno nuevo con los cambios. Esto se logra típicamente con &lt;code&gt;Object.assign()&lt;/code&gt;, el operador spread (&lt;code&gt;...&lt;/code&gt;), o métodos como &lt;code&gt;.map()&lt;/code&gt; para arrays. La función debe devolver la estructura (potencialmente modificada).&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Lógica Central:&lt;/strong&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;Chequeo Inicial (Caso Base Parcial):&lt;/strong&gt; ¿Es el &lt;code&gt;nodo&lt;/code&gt; actual &lt;code&gt;null&lt;/code&gt; o no es un objeto/array? Si es así, no podemos buscar dentro, retornamos el nodo tal cual.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Chequeo de ID (Caso Base Principal):&lt;/strong&gt; ¿Tiene el &lt;code&gt;nodo&lt;/code&gt; actual el &lt;code&gt;targetId&lt;/code&gt; buscado?

&lt;ul&gt;
&lt;li&gt;  Si sí: Crea una &lt;strong&gt;copia&lt;/strong&gt; del nodo, modifica el campo deseado en la copia y retorna la copia. ¡Éxito!&lt;/li&gt;
&lt;li&gt;  Si no: Proceder al paso recursivo.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt; &lt;strong&gt;Paso Recursivo (Manejo de Tipos):&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Si el &lt;code&gt;nodo&lt;/code&gt; es un Array:&lt;/strong&gt; Itera sobre cada elemento. Llama recursivamente a la función con cada elemento. Construye un &lt;strong&gt;nuevo array&lt;/strong&gt; con los resultados de estas llamadas recursivas (usando &lt;code&gt;.map()&lt;/code&gt; es ideal para inmutabilidad). Retorna el nuevo array.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Si el &lt;code&gt;nodo&lt;/code&gt; es un Objeto (y no un array):&lt;/strong&gt; Itera sobre las claves (&lt;code&gt;Object.keys()&lt;/code&gt;). Llama recursivamente a la función con el valor de cada propiedad. Construye un &lt;strong&gt;nuevo objeto&lt;/strong&gt; acumulando los resultados. Retorna el nuevo objeto.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ol&gt;

&lt;/li&gt;

&lt;/ul&gt;

&lt;/li&gt;

&lt;li&gt;&lt;p&gt;&lt;strong&gt;(Nota de Repaso):&lt;/strong&gt; La clave es &lt;strong&gt;verificar el ID&lt;/strong&gt; en el nivel actual. Si no coincide, &lt;strong&gt;delegar la búsqueda a los hijos&lt;/strong&gt; (elementos de array o valores de propiedades de objeto) llamando a la misma función sobre ellos. Siempre &lt;strong&gt;construir y retornar nuevas estructuras&lt;/strong&gt; (arrays/objetos) para mantener la inmutabilidad.&lt;/p&gt;&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;4. Ejemplo Práctico (JavaScript)&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="cm"&gt;/**
 * Busca recursivamente un item por ID en una estructura anidada
 * y actualiza un campo específico de forma inmutable.
 *
 * @param {object|array} data La estructura de datos donde buscar.
 * @param {string|number} targetId El ID del item a buscar.
 * @param {string} fieldToUpdate El nombre del campo a modificar en el item encontrado.
 * @param {*} newValue El nuevo valor para el campo.
 * @returns {object|array} La nueva estructura de datos con el item modificado (o la original si no se encontró).
 */&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;updateNestedItemById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;targetId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;fieldToUpdate&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;newValue&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Caso Base 1: Si no es objeto/array, no podemos buscar dentro.&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;object&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// Si es un Array: Procesar cada elemento recursivamente&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;isArray&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Usamos map para crear un NUEVO array con los resultados&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;updateNestedItemById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;targetId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;fieldToUpdate&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;newValue&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// Si es un Objeto:&lt;/span&gt;
    &lt;span class="c1"&gt;// Caso Base 2: ¿Es este el objeto que buscamos?&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;targetId&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// ¡Encontrado! Crear copia y modificar el campo especificado.&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`-- Encontrado item con ID: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;targetId&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;. Actualizando campo '&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;fieldToUpdate&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;'.`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// Copia inmutable de las propiedades existentes&lt;/span&gt;
            &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;fieldToUpdate&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="nx"&gt;newValue&lt;/span&gt; &lt;span class="c1"&gt;// Actualiza/añade el campo específico&lt;/span&gt;
        &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// Paso Recursivo para Objetos: Procesar cada propiedad recursivamente&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;updatedObject&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{};&lt;/span&gt; &lt;span class="c1"&gt;// Empezar con un objeto vacío para la nueva versión&lt;/span&gt;
    &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;hasOwnProperty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// Llamada recursiva para el valor de la propiedad&lt;/span&gt;
            &lt;span class="nx"&gt;updatedObject&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;updateNestedItemById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="nx"&gt;targetId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;fieldToUpdate&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;newValue&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;updatedObject&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Retornar el nuevo objeto construido&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// --- Ejemplo de Uso ---&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;initialData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Root&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;children&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;11&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Child 1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;active&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;children&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Child 2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;pending&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;children&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;121&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Grandchild 2.1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;active&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;]}&lt;/span&gt;
    &lt;span class="p"&gt;]},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Another Root&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;inactive&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;];&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Datos Iniciales:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;initialData&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

&lt;span class="c1"&gt;// Modificar el status del item con id 12 a 'completed'&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;targetIdToUpdate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;field&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;status&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;completed&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;updatedData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;updateNestedItemById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;initialData&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;targetIdToUpdate&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;field&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;Datos Actualizados:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;updatedData&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

&lt;span class="c1"&gt;// Verificar que el original no cambió (si hicimos bien la inmutabilidad)&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;Datos Originales (sin cambios):&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;initialData&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

&lt;span class="c1"&gt;// Intentar actualizar un ID que no existe&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;nonExistentUpdate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;updateNestedItemById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;initialData&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;999&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;status&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;failed&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// Debería ser igual a initialData&lt;/span&gt;
&lt;span class="c1"&gt;// console.log("\nIntento con ID no existente:", JSON.stringify(nonExistentUpdate, null, 2));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;5. Buenas Prácticas y Consideraciones Adicionales:&lt;/strong&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;*   **Inmutabilidad:** Como se demostró, usar `map` para arrays y crear nuevos objetos con el operador spread (`...`) o `Object.assign()` es crucial para evitar efectos secundarios inesperados.
*   **Stack Overflow:** Con estructuras *extremadamente* profundas, la recursión puede exceder el límite de la pila de llamadas. En esos casos (raros en datos JSON típicos, pero posibles), se podría considerar una solución iterativa usando una pila manual.
*   **Performance:** Para estructuras gigantescas, la creación constante de nuevos objetos/arrays puede tener un impacto en la memoria/rendimiento. Evaluar si es un problema real antes de optimizar prematuramente. Librerías como Immer.js pueden ayudar a manejar la inmutabilidad de forma más eficiente.
*   **Complejidad del Objeto:** El ejemplo asume que el ID está en una propiedad llamada `id`. La función podría hacerse más flexible para aceptar una función `finder` o el nombre de la propiedad ID.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt; ¡No olvides el &lt;strong&gt;caso base&lt;/strong&gt;! Sin él, tu función recursiva correrá indefinidamente (o hasta que la pila se desborde). Asegúrate de manejar tanto objetos como arrays correctamente en tu paso recursivo.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;(Nota de Repaso):&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Do:&lt;/strong&gt; Tener un caso base claro para detener la recursión. Manejar objetos y arrays. Priorizar la inmutabilidad (crear copias).&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Don't:&lt;/strong&gt; Olvidar el caso base. Modificar los datos originales directamente (mutación). Usar recursión si un simple bucle es suficiente (para estructuras planas).&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;6. Resumen / Puntos Clave para el Repaso:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Recursión:&lt;/strong&gt; Función que se llama a sí misma.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Componentes:&lt;/strong&gt; &lt;strong&gt;Caso Base&lt;/strong&gt; (detiene) y &lt;strong&gt;Paso Recursivo&lt;/strong&gt; (continúa con subproblema).&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Aplicación:&lt;/strong&gt; Ideal para &lt;strong&gt;estructuras anidadas&lt;/strong&gt; (objetos/arrays dentro de otros).&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Proceso:&lt;/strong&gt;

&lt;ol&gt;
&lt;li&gt; Verificar ID en el nodo actual (si aplica).&lt;/li&gt;
&lt;li&gt; Si es el nodo, &lt;strong&gt;copiar y modificar&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt; Si no es el nodo, &lt;strong&gt;llamar recursivamente&lt;/strong&gt; a la función para cada hijo/propiedad.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Construir&lt;/strong&gt; la nueva estructura (array/objeto) con los resultados de las llamadas recursivas.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Inmutabilidad:&lt;/strong&gt; Esencial para código predecible; crear copias en lugar de modificar originales.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;7. Preguntas de Autoevaluación:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; ¿Cuál es el propósito principal del "caso base" en una función recursiva?&lt;/li&gt;
&lt;li&gt; En el ejemplo de código, ¿cómo se asegura la inmutabilidad al procesar un array? ¿Y al procesar un objeto que no es el objetivo?&lt;/li&gt;
&lt;li&gt; ¿Qué pasaría si la función &lt;code&gt;updateNestedItemById&lt;/code&gt; no retornara nada en el paso recursivo (cuando procesa hijos)?&lt;/li&gt;
&lt;/ol&gt;




&lt;p&gt;Espero que este artículo detallado te sirva como una excelente guía y nota de repaso sobre cómo usar la recursión para esta tarea específica. ¡Avísame si quieres explorar otro tema!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>📘 Clase `Num` en TypeScript 🤓</title>
      <dc:creator>Cristian Arieta</dc:creator>
      <pubDate>Fri, 04 Apr 2025 21:12:06 +0000</pubDate>
      <link>https://dev.to/cristian_arieta_7df932e5f/clase-num-en-typescript-1ah8</link>
      <guid>https://dev.to/cristian_arieta_7df932e5f/clase-num-en-typescript-1ah8</guid>
      <description>&lt;h2&gt;
  
  
  🧱 ¿Qué es una clase &lt;code&gt;Num&lt;/code&gt;?
&lt;/h2&gt;

&lt;p&gt;Una &lt;strong&gt;clase &lt;code&gt;Num&lt;/code&gt; (o &lt;code&gt;Numero&lt;/code&gt;)&lt;/strong&gt; no es parte de Angular ni de TypeScript por defecto, pero &lt;strong&gt;tú puedes crearla como una estructura personalizada&lt;/strong&gt; para manejar números con ciertas operaciones u objetos más estructurados.&lt;/p&gt;

&lt;p&gt;Se utiliza cuando quieres encapsular &lt;strong&gt;propiedades, validaciones, y métodos matemáticos&lt;/strong&gt; que trabajan alrededor de un número.&lt;/p&gt;




&lt;h3&gt;
  
  
  🔨 Ejemplo base de una clase &lt;code&gt;Num&lt;/code&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Num&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;valor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;valor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;valor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;valor&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;getValue&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;valor&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;isEven&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;valor&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;double&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;valor&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;`📦 Valor actual: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;valor&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  ✅ Uso de la clase &lt;code&gt;Num&lt;/code&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;miNumero&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Num&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;miNumero&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getValue&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt; &lt;span class="c1"&gt;// 6&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;¿Es par?&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;miNumero&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;isEven&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt; &lt;span class="c1"&gt;// true&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Doble:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;miNumero&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;double&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt; &lt;span class="c1"&gt;// 12&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;miNumero&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt; &lt;span class="c1"&gt;// 📦 Valor actual: 6&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🎯 ¿Para qué sirve crear una clase &lt;code&gt;Num&lt;/code&gt;?
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;✅ Para encapsular reglas o validaciones personalizadas&lt;/li&gt;
&lt;li&gt;🧪 Para tener lógica reutilizable sobre números (sumar, restar, convertir, validar)&lt;/li&gt;
&lt;li&gt;📦 Para trabajar en proyectos grandes donde un simple &lt;code&gt;number&lt;/code&gt; ya no es suficiente&lt;/li&gt;
&lt;li&gt;🧠 Para aprender los principios POO (Programación Orientada a Objetos)&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  💡 Ejemplo avanzado: clase &lt;code&gt;Num&lt;/code&gt; con operaciones matemáticas
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Num&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;valor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

  &lt;span class="nf"&gt;suma&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;Num&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Num&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;valor&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;resta&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;Num&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Num&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;valor&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;multiplica&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;Num&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Num&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;valor&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;divide&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;Num&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;❌ División por cero no permitida&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Num&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;valor&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;esPositivo&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;valor&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;imprimir&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`📦 Valor: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;valor&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  🧪 Uso:
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;numero&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Num&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;numero&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;imprimir&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// 📦 Valor: 10&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;resultado&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;numero&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;suma&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;multiplica&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// (10 + 5) * 2 = 30&lt;/span&gt;
&lt;span class="nx"&gt;resultado&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;imprimir&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// 📦 Valor: 30&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;¿Es positivo?&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;resultado&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;esPositivo&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt; &lt;span class="c1"&gt;// true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🧙‍♂️ Ventajas de usar esta clase &lt;code&gt;Num&lt;/code&gt;
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Ventaja&lt;/th&gt;
&lt;th&gt;¿Por qué importa?&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Encapsulamiento&lt;/td&gt;
&lt;td&gt;Protege y controla el acceso al valor&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Métodos encadenables&lt;/td&gt;
&lt;td&gt;Permite operaciones más limpias y elegantes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Validación centralizada&lt;/td&gt;
&lt;td&gt;Puedes agregar reglas como "no dividir entre 0"&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Reutilización&lt;/td&gt;
&lt;td&gt;Puedes usar &lt;code&gt;Num&lt;/code&gt; en varios proyectos o módulos&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  📌 Detalles técnicos
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;✅ Puedes usar &lt;code&gt;private&lt;/code&gt; para evitar que otros modifiquen el número directamente&lt;/li&gt;
&lt;li&gt;✅ Puedes extender &lt;code&gt;Num&lt;/code&gt; para crear por ejemplo &lt;code&gt;Porcentaje extends Num&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;✅ Puedes sobreescribir el método &lt;code&gt;toString()&lt;/code&gt; para imprimir bonito&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🧁 Postre final: Mini práctica para ti
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
ts
// Crea una clase Num que tenga:
// - una propiedad valor (número)
// - un método cuadrado()
// - un método raiz()
// - un método negativo()
// - un método mostrar()


---
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

</description>
    </item>
    <item>
      <title>¿Qué es el tipado en TypeScript?</title>
      <dc:creator>Cristian Arieta</dc:creator>
      <pubDate>Fri, 04 Apr 2025 21:04:33 +0000</pubDate>
      <link>https://dev.to/cristian_arieta_7df932e5f/que-es-el-tipado-en-typescript-5369</link>
      <guid>https://dev.to/cristian_arieta_7df932e5f/que-es-el-tipado-en-typescript-5369</guid>
      <description>&lt;p&gt;Vamos a aprender &lt;strong&gt;todos los tipos (tipados)&lt;/strong&gt; que existen en &lt;strong&gt;TypeScript&lt;/strong&gt;, con su explicación y un ejemplo por cada uno.&lt;/p&gt;

&lt;p&gt;Prepárate, que esto va cargado de conocimiento y emojis 😄📚&lt;/p&gt;

&lt;p&gt;TypeScript es un &lt;strong&gt;superset de JavaScript&lt;/strong&gt; que &lt;strong&gt;añade tipos estáticos&lt;/strong&gt;.&lt;br&gt;&lt;br&gt;
Eso significa que puedes decirle al código &lt;strong&gt;qué tipo de dato debe tener una variable&lt;/strong&gt;, y así evitar errores antes de que el programa corra. ✅❌&lt;/p&gt;


&lt;h2&gt;
  
  
  🗂️ Tipos primitivos (los básicos)
&lt;/h2&gt;
&lt;h3&gt;
  
  
  1️⃣ &lt;code&gt;string&lt;/code&gt; – Cadenas de texto
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;nombre&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Cristian Zayas&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;🗣️ Sirve para cualquier texto entre comillas.&lt;/p&gt;


&lt;h3&gt;
  
  
  2️⃣ &lt;code&gt;number&lt;/code&gt; – Números (enteros y decimales)
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;edad&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;temperatura&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;36.6&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;🧮 Nada de &lt;code&gt;int&lt;/code&gt; o &lt;code&gt;float&lt;/code&gt;, aquí todo es &lt;code&gt;number&lt;/code&gt;.&lt;/p&gt;


&lt;h3&gt;
  
  
  3️⃣ &lt;code&gt;boolean&lt;/code&gt; – Verdadero o falso
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;estaActivo&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;🔘 Útil para condiciones, estados y validaciones.&lt;/p&gt;


&lt;h3&gt;
  
  
  4️⃣ &lt;code&gt;null&lt;/code&gt; – Valor nulo (ausente intencionalmente)
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;resultado&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;🚫 Ideal para indicar que algo no tiene valor.&lt;/p&gt;


&lt;h3&gt;
  
  
  5️⃣ &lt;code&gt;undefined&lt;/code&gt; – Aún no se ha definido
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;mensaje&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;📦 Se usa cuando no se ha asignado valor todavía.&lt;/p&gt;


&lt;h3&gt;
  
  
  6️⃣ &lt;code&gt;symbol&lt;/code&gt; – Valor único e inmutable
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;symbol&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Symbol&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;id&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;🔐 Útil en estructuras muy avanzadas o bibliotecas.&lt;/p&gt;


&lt;h3&gt;
  
  
  7️⃣ &lt;code&gt;bigint&lt;/code&gt; – Números grandes
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;numeroGrande&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;bigint&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;9007199254740991&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;📏 Para cálculos de números gigantes que sobrepasan los límites de &lt;code&gt;number&lt;/code&gt;.&lt;/p&gt;


&lt;h2&gt;
  
  
  🧺 Tipos estructurados
&lt;/h2&gt;
&lt;h3&gt;
  
  
  8️⃣ &lt;code&gt;array&lt;/code&gt; – Arreglos
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;frutas&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Manzana&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Banana&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Mango&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;📚 También se puede usar &lt;code&gt;Array&amp;lt;string&amp;gt;&lt;/code&gt;.&lt;/p&gt;


&lt;h3&gt;
  
  
  9️⃣ &lt;code&gt;tuple&lt;/code&gt; – Arreglos con tipos fijos
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;coordenada&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;📌 Útil para valores en par (como coordenadas, RGB, etc.)&lt;/p&gt;


&lt;h3&gt;
  
  
  🔟 &lt;code&gt;object&lt;/code&gt; – Objetos con propiedades
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;persona&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;nombre&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;edad&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;nombre&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Ana&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;edad&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;28&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;📦 Puedes crear interfaces para reutilizar:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;Usuario&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;nombre&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;correo&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Usuario&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;nombre&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Zayas&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;correo&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;zayas@mail.com&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🧩 Tipos especiales
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1️⃣1️⃣ &lt;code&gt;any&lt;/code&gt; – Cualquier tipo (pierdes seguridad de tipos)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;variable&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;variable&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ahora soy texto&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;⚠️ Úsalo solo cuando no hay otra opción.&lt;/p&gt;




&lt;h3&gt;
  
  
  1️⃣2️⃣ &lt;code&gt;unknown&lt;/code&gt; – Tipo desconocido, pero más seguro que &lt;code&gt;any&lt;/code&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;dato&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;unknown&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;hola&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// dato.toUpperCase(); ❌ Error&lt;/span&gt;
&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;dato&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;string&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;dato&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toUpperCase&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt; &lt;span class="c1"&gt;// ✅&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;🔐 Obliga a verificar el tipo antes de usarlo.&lt;/p&gt;




&lt;h3&gt;
  
  
  1️⃣3️⃣ &lt;code&gt;void&lt;/code&gt; – No devuelve nada (funciones sin retorno)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;saludar&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Hola dev 👋&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;🫙 Se usa para funciones que solo ejecutan, no retornan.&lt;/p&gt;




&lt;h3&gt;
  
  
  1️⃣4️⃣ &lt;code&gt;never&lt;/code&gt; – Nunca retorna (errores, bucles infinitos)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nx"&gt;never&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;¡Algo salió mal!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;🚫 Ideal para funciones que &lt;strong&gt;nunca terminan correctamente&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  💥 Tipos combinados
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1️⃣5️⃣ Union types – Uno u otro
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;valor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Hola&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;valor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// también válido&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;⚔️ Muy útil para parámetros que aceptan más de un tipo.&lt;/p&gt;




&lt;h3&gt;
  
  
  1️⃣6️⃣ Literal types – Valores específicos
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;direccion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;izquierda&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;derecha&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;izquierda&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;📍 Útil cuando solo se permiten ciertos valores.&lt;/p&gt;




&lt;h3&gt;
  
  
  1️⃣7️⃣ Type alias – Alias de tipos
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;ID&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;usuarioID&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ID&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;123&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;📦 Reutiliza estructuras complejas con nombres sencillos.&lt;/p&gt;




&lt;h3&gt;
  
  
  1️⃣8️⃣ Enum – Enumeraciones (grupos de valores constantes)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kr"&gt;enum&lt;/span&gt; &lt;span class="nx"&gt;Rol&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;Admin&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;Usuario&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;Invitado&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;rolActual&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Rol&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Rol&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Admin&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;🧭 Ideal para estados, roles, opciones predefinidas.&lt;/p&gt;




&lt;h2&gt;
  
  
  🧠 Resumen en tabla
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tipo&lt;/th&gt;
&lt;th&gt;Descripción&lt;/th&gt;
&lt;th&gt;Ejemplo&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;string&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Texto&lt;/td&gt;
&lt;td&gt;&lt;code&gt;'Hola'&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;number&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Número&lt;/td&gt;
&lt;td&gt;&lt;code&gt;42&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;boolean&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Verdadero o falso&lt;/td&gt;
&lt;td&gt;&lt;code&gt;true&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;null&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Valor nulo&lt;/td&gt;
&lt;td&gt;&lt;code&gt;null&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;undefined&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;No definido&lt;/td&gt;
&lt;td&gt;&lt;code&gt;undefined&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;symbol&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Identificador único&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Symbol('id')&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;bigint&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Números grandes&lt;/td&gt;
&lt;td&gt;&lt;code&gt;1234567890123456789n&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;array&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Lista de valores&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[1, 2, 3]&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;tuple&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Lista con tipos específicos&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[true, 'hola']&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;object&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Estructura con propiedades&lt;/td&gt;
&lt;td&gt;&lt;code&gt;{ nombre: 'Zayas' }&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;any&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Puede ser cualquier tipo&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;'texto'&lt;/code&gt;, &lt;code&gt;42&lt;/code&gt;, etc.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;unknown&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Similar a &lt;code&gt;any&lt;/code&gt; pero más seguro&lt;/td&gt;
&lt;td&gt;&lt;code&gt;let x: unknown = true;&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;void&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Sin valor de retorno&lt;/td&gt;
&lt;td&gt;&lt;code&gt;function hola(): void {}&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;never&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Nunca retorna&lt;/td&gt;
&lt;td&gt;&lt;code&gt;function crash(): never {}&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;union&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Puede ser uno u otro&lt;/td&gt;
&lt;td&gt;`string&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;{% raw %}&lt;code&gt;literal&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Solo acepta valores específicos&lt;/td&gt;
&lt;td&gt;`'ON'&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;{% raw %}&lt;code&gt;type alias&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Tipo con nombre personalizado&lt;/td&gt;
&lt;td&gt;`type ID = string&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;{% raw %}&lt;code&gt;enum&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Conjunto de valores nombrados&lt;/td&gt;
&lt;td&gt;&lt;code&gt;enum Color { Rojo, Azul }&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  🧪 ¿Listo para practicar?
&lt;/h2&gt;

&lt;p&gt;¿Qué tipo sería ideal para representar:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;estado&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;activo&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// solo puede ser 'activo' o 'inactivo'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;✅ R: Un &lt;strong&gt;literal type&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;estado&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;activo&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;inactivo&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;activo&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






</description>
    </item>
    <item>
      <title>🎯 Las validaciones ternarias en TypeScript (y también en HTML con Angular)</title>
      <dc:creator>Cristian Arieta</dc:creator>
      <pubDate>Fri, 04 Apr 2025 21:00:02 +0000</pubDate>
      <link>https://dev.to/cristian_arieta_7df932e5f/las-validaciones-ternarias-en-typescript-y-tambien-en-html-con-angular-16fk</link>
      <guid>https://dev.to/cristian_arieta_7df932e5f/las-validaciones-ternarias-en-typescript-y-tambien-en-html-con-angular-16fk</guid>
      <description>&lt;p&gt;Hoy vamos a hablar de un tema que suena complicado pero es &lt;strong&gt;súper útil y elegante&lt;/strong&gt;:  &lt;/p&gt;




&lt;h2&gt;
  
  
  🧠 ¿Qué es una validación ternaria?
&lt;/h2&gt;

&lt;p&gt;La validación ternaria (o &lt;strong&gt;operador ternario&lt;/strong&gt;) es como un &lt;strong&gt;"if" en una sola línea&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;📚 Su estructura es:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;condición&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;valorSiEsVerdadero&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;valorSiEsFalso&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Es como decir:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Si esto es verdadero, haz esto; si no, haz lo otro” — ¡pero todo en una línea! 🎩&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h3&gt;
  
  
  🧪 Ejemplo básico en TypeScript
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;edad&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;mensaje&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;edad&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;18&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Eres mayor de edad 🧔&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Eres menor de edad 👶&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;mensaje&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Eres mayor de edad 🧔&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;👉 Lo mismo con &lt;code&gt;if&lt;/code&gt; sería:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;mensaje&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;edad&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;18&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;mensaje&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Eres mayor de edad 🧔&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;mensaje&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Eres menor de edad 👶&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;🧼 ¿Ves la diferencia? El operador ternario es más limpio, directo y legible cuando son decisiones cortas.&lt;/p&gt;




&lt;h2&gt;
  
  
  🧩 ¿Y en Angular HTML con &lt;code&gt;*ngIf&lt;/code&gt; o atributos?
&lt;/h2&gt;

&lt;p&gt;También puedes usarlo directamente en la plantilla HTML, por ejemplo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;[style.color]=&lt;/span&gt;&lt;span class="s"&gt;"isError ? 'red' : 'green'"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  {{ isError ? '¡Ups, error!' : 'Todo bien 👍' }}
&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  🧪 Otro ejemplo: mostrar íconos según estado
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;fa-icon&lt;/span&gt; &lt;span class="na"&gt;[icon]=&lt;/span&gt;&lt;span class="s"&gt;"isOnline ? 'wifi' : 'wifi-slash'"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/fa-icon&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Esto cambia el ícono dependiendo si &lt;code&gt;isOnline&lt;/code&gt; es &lt;code&gt;true&lt;/code&gt; o &lt;code&gt;false&lt;/code&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  ⚠️ Cuándo &lt;strong&gt;NO&lt;/strong&gt; usar ternarias
&lt;/h2&gt;

&lt;p&gt;Evita ternarias cuando la lógica se complica mucho o hay varios niveles anidados 😵‍💫:&lt;/p&gt;

&lt;p&gt;❌ Mal uso:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;mensaje&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt; 
  &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt; 
    &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Alto y bien&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; 
    &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Alto pero mal&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; 
  &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Bajo&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;En ese caso, es mejor usar &lt;code&gt;if/else&lt;/code&gt; para mantenerlo claro.&lt;/p&gt;




&lt;h2&gt;
  
  
  ✅ Cuándo SÍ usar ternarias
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Mostrar mensajes cortos en función de una condición&lt;/li&gt;
&lt;li&gt;Cambiar estilos dinámicos&lt;/li&gt;
&lt;li&gt;Elegir entre dos valores&lt;/li&gt;
&lt;li&gt;Dentro de interpolaciones en Angular&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🧭 En resumen:
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Parte&lt;/th&gt;
&lt;th&gt;Descripción&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;condición&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Se evalúa como &lt;code&gt;true&lt;/code&gt; o &lt;code&gt;false&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;? valorSiTrue&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Se ejecuta si la condición es verdadera&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;: valorSiFalse&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Se ejecuta si es falsa&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h3&gt;
  
  
  🚀 Ejercicio Rápido
&lt;/h3&gt;

&lt;p&gt;¿Qué muestra este código?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;nivel&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;resultado&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;nivel&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;✅ Aprobado&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;❌ Reprobado&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;resultado&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;🧠 Piensa unos segundos...&lt;br&gt;&lt;br&gt;
¡Correcto! Muestra: &lt;code&gt;✅ Aprobado&lt;/code&gt;&lt;/p&gt;




</description>
    </item>
    <item>
      <title>🚀 ¡A Navegar con Bucles en Angular!</title>
      <dc:creator>Cristian Arieta</dc:creator>
      <pubDate>Fri, 04 Apr 2025 20:52:47 +0000</pubDate>
      <link>https://dev.to/cristian_arieta_7df932e5f/a-navegar-con-bucles-en-angular-ao</link>
      <guid>https://dev.to/cristian_arieta_7df932e5f/a-navegar-con-bucles-en-angular-ao</guid>
      <description>&lt;h3&gt;
  
  
  Aprende a repetir elementos como todo un Capitán 🧑‍✈️⚓
&lt;/h3&gt;

&lt;p&gt;Hola devs 👩‍💻👨‍💻, hoy vamos a abordar un tema súper útil en Angular: &lt;strong&gt;los bucles&lt;/strong&gt;.&lt;br&gt;&lt;br&gt;
Así como un barco recorre el mar parando en varias islas 🏝️, &lt;strong&gt;los bucles recorren colecciones de datos&lt;/strong&gt;, mostrando o procesando cada elemento.&lt;/p&gt;

&lt;p&gt;Vamos a ver cómo se hace esto en Angular paso a paso, con ejemplos y emojis para no dormirnos 😴👉😄.&lt;/p&gt;


&lt;h3&gt;
  
  
  1️⃣ &lt;code&gt;*ngFor&lt;/code&gt; en el HTML – El timón del barco 🚢
&lt;/h3&gt;

&lt;p&gt;Imagina que tienes una lista de frutas tropicales 🍍🍌🥭 que quieres mostrar en pantalla. ¡Aquí entra &lt;code&gt;*ngFor&lt;/code&gt; al rescate!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// archivo: frutas.component.ts&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;FrutasComponent&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;frutas&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Piña 🍍&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Banano 🍌&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Mango 🥭&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Y en el HTML:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- archivo: frutas.component.html --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;ul&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;li&lt;/span&gt; &lt;span class="na"&gt;*ngFor=&lt;/span&gt;&lt;span class="s"&gt;"let fruta of frutas"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;{{ fruta }}&lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/ul&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;📌 Explicación:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;*ngFor&lt;/code&gt; recorre cada elemento de &lt;code&gt;frutas&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;let fruta of frutas&lt;/code&gt; crea una variable &lt;code&gt;fruta&lt;/code&gt; por cada elemento.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;{{ fruta }}&lt;/code&gt; lo muestra en pantalla.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;🧠 ¡Fácil y limpio! Y se ve así:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- Piña 🍍
- Banano 🍌
- Mango 🥭
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  2️⃣ Bucles en TypeScript – Los motores del barco 🛠️
&lt;/h3&gt;

&lt;p&gt;Ahora supongamos que quieres hacer algo &lt;strong&gt;con lógica&lt;/strong&gt;, como filtrar frutas o convertirlas a mayúsculas.&lt;/p&gt;

&lt;h4&gt;
  
  
  🧪 Ejemplo con &lt;code&gt;for&lt;/code&gt; tradicional:
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;frutas&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Fruta #&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;frutas&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  🧪 Ejemplo con &lt;code&gt;forEach&lt;/code&gt;:
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;frutas&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;fruta&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Fruta &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;index&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;fruta&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toUpperCase&lt;/span&gt;&lt;span class="p"&gt;()}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  🧪 Ejemplo con &lt;code&gt;map&lt;/code&gt; para transformar:
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;frutasEnMayuscula&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;frutas&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fruta&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;fruta&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toUpperCase&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;frutasEnMayuscula&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// ['PIÑA 🍍', 'BANANO 🍌', 'MANGO 🥭']&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  3️⃣ Bonus: &lt;code&gt;ng-template&lt;/code&gt; para más control 🧙‍♂️
&lt;/h3&gt;

&lt;p&gt;Puedes usar &lt;code&gt;ng-template&lt;/code&gt; si quieres mostrar un mensaje cuando no haya datos. Ejemplo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;ul&lt;/span&gt; &lt;span class="na"&gt;*ngIf=&lt;/span&gt;&lt;span class="s"&gt;"frutas.length &amp;gt; 0; else noHayFrutas"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;li&lt;/span&gt; &lt;span class="na"&gt;*ngFor=&lt;/span&gt;&lt;span class="s"&gt;"let fruta of frutas"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;{{ fruta }}&lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/ul&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;ng-template&lt;/span&gt; &lt;span class="na"&gt;#noHayFrutas&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;No hay frutas para mostrar 🍽️&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/ng-template&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🧭 Resumen del Capitán
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Herramienta&lt;/th&gt;
&lt;th&gt;¿Para qué sirve?&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;*ngFor&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Mostrar listas en HTML&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;for&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Bucle clásico, útil para lógica más compleja&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;forEach&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Recorre arrays, sin modificar&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;map&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Transforma arrays y devuelve uno nuevo&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ng-template&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Muestra contenido alternativo (como un &lt;code&gt;else&lt;/code&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  🚀 ¡Zarpa y practica!
&lt;/h2&gt;

&lt;h2&gt;
  
  
  Los bucles son parte del alma de una app dinámica. Ya sea mostrando productos 🛍️, usuarios 👥 o posts 📝, sabrás cómo hacerlos navegar con estilo.
&lt;/h2&gt;

</description>
    </item>
    <item>
      <title>🚀 Virtual Scroll en Angular: ¡Carga listas infinitas sin perder rendimiento!</title>
      <dc:creator>Cristian Arieta</dc:creator>
      <pubDate>Thu, 03 Apr 2025 17:38:00 +0000</pubDate>
      <link>https://dev.to/cristian_arieta_7df932e5f/-virtual-scroll-en-angular-carga-listas-infinitas-sin-perder-rendimiento-e41</link>
      <guid>https://dev.to/cristian_arieta_7df932e5f/-virtual-scroll-en-angular-carga-listas-infinitas-sin-perder-rendimiento-e41</guid>
      <description>&lt;h2&gt;
  
  
  🧐 &lt;strong&gt;¿Qué es Virtual Scroll?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Virtual Scroll es una técnica de renderizado en la que &lt;strong&gt;solo se dibujan los elementos visibles en pantalla&lt;/strong&gt; en lugar de cargar toda la lista en el DOM.  &lt;/p&gt;

&lt;p&gt;📌 &lt;strong&gt;Beneficios&lt;/strong&gt;:&lt;br&gt;&lt;br&gt;
✅ Mejora el rendimiento en listas largas.&lt;br&gt;&lt;br&gt;
✅ Reduce el consumo de memoria y procesamiento.&lt;br&gt;&lt;br&gt;
✅ Hace que la interfaz sea más fluida y rápida.  &lt;/p&gt;

&lt;p&gt;🔥 &lt;strong&gt;Ejemplo clásico sin Virtual Scroll:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Si tienes una lista de &lt;strong&gt;10,000 elementos&lt;/strong&gt;, Angular los renderiza &lt;strong&gt;todos&lt;/strong&gt; en el DOM, haciendo que la página se vuelva &lt;strong&gt;lenta y pesada&lt;/strong&gt;.  &lt;/p&gt;

&lt;p&gt;💡 &lt;strong&gt;Con Virtual Scroll&lt;/strong&gt;, solo se renderizan los elementos visibles en pantalla, cargando los demás &lt;strong&gt;dinámicamente&lt;/strong&gt; a medida que el usuario se desplaza.  &lt;/p&gt;


&lt;h2&gt;
  
  
  📌 &lt;strong&gt;¿Cuándo usar Virtual Scroll?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;🔹 Listas con &lt;strong&gt;muchos elementos&lt;/strong&gt; (1000+).&lt;br&gt;&lt;br&gt;
🔹 Cuando el rendimiento &lt;strong&gt;se ve afectado&lt;/strong&gt; por demasiados elementos en pantalla.&lt;br&gt;&lt;br&gt;
🔹 Cuando necesitas &lt;strong&gt;optimizar&lt;/strong&gt; el uso de memoria y mejorar la UX.  &lt;/p&gt;


&lt;h2&gt;
  
  
  🛠 &lt;strong&gt;Implementación de Virtual Scroll en Angular&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Para usar Virtual Scroll en Angular, necesitamos &lt;strong&gt;Angular CDK (Component Dev Kit)&lt;/strong&gt;, que proporciona herramientas para mejorar la interfaz de usuario.  &lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;1️⃣ Instalar Angular CDK&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Si aún no tienes instalado Angular CDK, agrégalo con este comando:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; @angular/cdk
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  &lt;strong&gt;2️⃣ Importar &lt;code&gt;ScrollingModule&lt;/code&gt; en tu módulo&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Abre el archivo &lt;code&gt;app.module.ts&lt;/code&gt; e importa el módulo de desplazamiento:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ScrollingModule&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@angular/cdk/scrolling&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;NgModule&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;imports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="nx"&gt;ScrollingModule&lt;/span&gt;  &lt;span class="c1"&gt;// 📌 Importamos el módulo&lt;/span&gt;
  &lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AppModule&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  &lt;strong&gt;3️⃣ Crear una lista con Virtual Scroll&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Ahora vamos a crear un componente con una lista de &lt;strong&gt;10,000 elementos&lt;/strong&gt;, pero solo renderizando los visibles.  &lt;/p&gt;

&lt;p&gt;📌 &lt;strong&gt;Código del componente (&lt;code&gt;virtual-scroll.component.ts&lt;/code&gt;)&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@angular/core&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;app-virtual-scroll&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;templateUrl&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./virtual-scroll.component.html&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;styleUrls&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./virtual-scroll.component.css&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;VirtualScrollComponent&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;items&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;length&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10000&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;`Elemento #&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;📌 &lt;strong&gt;Código del HTML (&lt;code&gt;virtual-scroll.component.html&lt;/code&gt;)&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;cdk-virtual-scroll-viewport&lt;/span&gt; &lt;span class="na"&gt;itemSize=&lt;/span&gt;&lt;span class="s"&gt;"50"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"scroll-container"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;*cdkVirtualFor=&lt;/span&gt;&lt;span class="s"&gt;"let item of items"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"item"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    {{ item }}
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/cdk-virtual-scroll-viewport&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;🎯 &lt;strong&gt;Explicación&lt;/strong&gt;:&lt;br&gt;&lt;br&gt;
✅ &lt;code&gt;&amp;lt;cdk-virtual-scroll-viewport&amp;gt;&lt;/code&gt; → Define el área de desplazamiento virtual.&lt;br&gt;&lt;br&gt;
✅ &lt;code&gt;itemSize="50"&lt;/code&gt; → Establece el tamaño de cada elemento en píxeles (ajústalo según el diseño).&lt;br&gt;&lt;br&gt;
✅ &lt;code&gt;*cdkVirtualFor="let item of items"&lt;/code&gt; → Funciona igual que &lt;code&gt;*ngFor&lt;/code&gt;, pero con Virtual Scroll.  &lt;/p&gt;



&lt;p&gt;📌 &lt;strong&gt;Código de estilos (&lt;code&gt;virtual-scroll.component.css&lt;/code&gt;)&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.scroll-container&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;400px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c"&gt;/* Altura fija del contenedor */&lt;/span&gt;
  &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;border&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1px&lt;/span&gt; &lt;span class="nb"&gt;solid&lt;/span&gt; &lt;span class="m"&gt;#ccc&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;overflow&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;auto&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.item&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;50px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c"&gt;/* Debe coincidir con itemSize */&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;align-items&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;10px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;border-bottom&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1px&lt;/span&gt; &lt;span class="nb"&gt;solid&lt;/span&gt; &lt;span class="m"&gt;#ddd&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🎯 &lt;strong&gt;¿Cómo funciona Virtual Scroll?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;1️⃣ El usuario &lt;strong&gt;desplaza la lista&lt;/strong&gt;.&lt;br&gt;&lt;br&gt;
2️⃣ Angular &lt;strong&gt;solo renderiza&lt;/strong&gt; los elementos visibles en el viewport.&lt;br&gt;&lt;br&gt;
3️⃣ Los elementos que salen de la vista &lt;strong&gt;se eliminan del DOM&lt;/strong&gt;, ahorrando memoria.&lt;br&gt;&lt;br&gt;
4️⃣ A medida que el usuario baja, &lt;strong&gt;se agregan nuevos elementos&lt;/strong&gt; dinámicamente.  &lt;/p&gt;


&lt;h2&gt;
  
  
  🔥 &lt;strong&gt;Mejoras avanzadas con Virtual Scroll&lt;/strong&gt;
&lt;/h2&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;1️⃣ Usar Virtual Scroll con una API (datos dinámicos)&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Si los datos provienen de una API, puedes combinarlos con Virtual Scroll para cargar información de forma eficiente.  &lt;/p&gt;

&lt;p&gt;Ejemplo con &lt;strong&gt;peticiones HTTP&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;OnInit&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@angular/core&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;HttpClient&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@angular/common/http&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;app-virtual-scroll-api&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;templateUrl&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./virtual-scroll-api.component.html&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;styleUrls&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./virtual-scroll-api.component.css&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;VirtualScrollApiComponent&lt;/span&gt; &lt;span class="k"&gt;implements&lt;/span&gt; &lt;span class="nx"&gt;OnInit&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;items&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;

  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;http&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;HttpClient&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

  &lt;span class="nf"&gt;ngOnInit&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;http&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;get&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://jsonplaceholder.typicode.com/posts&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;items&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;📌 &lt;strong&gt;HTML para la API (&lt;code&gt;virtual-scroll-api.component.html&lt;/code&gt;)&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;cdk-virtual-scroll-viewport&lt;/span&gt; &lt;span class="na"&gt;itemSize=&lt;/span&gt;&lt;span class="s"&gt;"50"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"scroll-container"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;*cdkVirtualFor=&lt;/span&gt;&lt;span class="s"&gt;"let item of items"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"item"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;strong&amp;gt;&lt;/span&gt;{{ item.id }}&lt;span class="nt"&gt;&amp;lt;/strong&amp;gt;&lt;/span&gt; - {{ item.title }}
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/cdk-virtual-scroll-viewport&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;🔥 &lt;strong&gt;Beneficio&lt;/strong&gt;:&lt;br&gt;&lt;br&gt;
En lugar de cargar &lt;strong&gt;todos los datos de la API en memoria&lt;/strong&gt;, solo se renderizan los visibles.  &lt;/p&gt;




&lt;h2&gt;
  
  
  📌 &lt;strong&gt;Diferencia entre Virtual Scroll y Paginación&lt;/strong&gt;
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Característica&lt;/th&gt;
&lt;th&gt;Virtual Scroll&lt;/th&gt;
&lt;th&gt;Paginación&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;🚀 &lt;strong&gt;Carga inicial&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;Solo elementos visibles&lt;/td&gt;
&lt;td&gt;Página completa&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;📏 &lt;strong&gt;Uso de memoria&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;Optimizado&lt;/td&gt;
&lt;td&gt;Puede ser alto&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;🔄 &lt;strong&gt;UX (experiencia de usuario)&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;Scroll fluido e infinito&lt;/td&gt;
&lt;td&gt;Cambio de página manual&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;⚡ &lt;strong&gt;Mejor rendimiento en grandes listas&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;✅ Sí&lt;/td&gt;
&lt;td&gt;❌ No tan eficiente&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;📌 &lt;strong&gt;¿Cuándo usar cuál?&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
🔹 Usa &lt;strong&gt;Virtual Scroll&lt;/strong&gt; cuando tienes &lt;strong&gt;grandes volúmenes de datos&lt;/strong&gt; y necesitas &lt;strong&gt;fluidez en la navegación&lt;/strong&gt;.&lt;br&gt;&lt;br&gt;
🔹 Usa &lt;strong&gt;Paginación&lt;/strong&gt; cuando los datos vienen de una API con muchas páginas y necesitas un &lt;strong&gt;control más preciso&lt;/strong&gt;.  &lt;/p&gt;




&lt;h2&gt;
  
  
  🎯 &lt;strong&gt;Conclusión&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;🔹 Virtual Scroll es ideal para &lt;strong&gt;listas largas&lt;/strong&gt; y mejora el rendimiento.&lt;br&gt;&lt;br&gt;
🔹 Usa &lt;strong&gt;&lt;code&gt;cdk-virtual-scroll-viewport&lt;/code&gt;&lt;/strong&gt; para implementar listas dinámicas.&lt;br&gt;&lt;br&gt;
🔹 Se combina bien con &lt;strong&gt;APIs&lt;/strong&gt; para cargar datos de manera eficiente.&lt;br&gt;&lt;br&gt;
🔹 Es una alternativa a la &lt;strong&gt;paginación&lt;/strong&gt;, dependiendo de la UX que necesites.  &lt;/p&gt;




&lt;h2&gt;
  
  
  🎓 &lt;strong&gt;¡Ahora es tu turno!&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;¿Qué opinas de Virtual Scroll? ¿Tienes dudas o quieres que veamos algún caso específico? ¡Estoy listo para ayudarte! 😃 🚀&lt;/p&gt;

</description>
      <category>angular</category>
      <category>typescript</category>
      <category>virtualmachine</category>
      <category>javascript</category>
    </item>
    <item>
      <title>🔥 ¿Cuándo se actualiza un componente con `OnPush`?</title>
      <dc:creator>Cristian Arieta</dc:creator>
      <pubDate>Wed, 02 Apr 2025 17:26:00 +0000</pubDate>
      <link>https://dev.to/cristian_arieta_7df932e5f/cuando-se-actualiza-un-componente-con-onpush-9j3</link>
      <guid>https://dev.to/cristian_arieta_7df932e5f/cuando-se-actualiza-un-componente-con-onpush-9j3</guid>
      <description>&lt;p&gt;Cuando un componente tiene &lt;strong&gt;OnPush&lt;/strong&gt;, solo se actualizará si ocurre &lt;strong&gt;alguna de estas situaciones&lt;/strong&gt;:  &lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;1️⃣ Cambio en un &lt;code&gt;@Input()&lt;/code&gt;&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Si el valor del &lt;code&gt;@Input()&lt;/code&gt; &lt;strong&gt;cambia de referencia&lt;/strong&gt;, Angular actualizará el componente.  &lt;/p&gt;

&lt;p&gt;✅ &lt;strong&gt;Se actualiza porque cambia la referencia (objeto nuevo)&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;producto&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;nombre&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Nuevo Producto&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt; 
&lt;span class="c1"&gt;// Esto genera una nueva referencia en memoria&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;❌ &lt;strong&gt;No se actualiza si solo se modifica una propiedad interna&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;producto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;nombre&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Nuevo Producto&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// No cambia la referencia del objeto en memoria, Angular no lo detecta&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;💡 &lt;strong&gt;Solución&lt;/strong&gt;: Para forzar la detección de cambios, asigna un nuevo objeto:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;producto&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;producto&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;nombre&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Nuevo Producto&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  &lt;strong&gt;2️⃣ Eventos del DOM (click, input, etc.)&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Si el componente tiene un evento como &lt;code&gt;(click)&lt;/code&gt;, &lt;code&gt;(input)&lt;/code&gt;, &lt;code&gt;(change)&lt;/code&gt;, etc., Angular detectará el cambio.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;(click)=&lt;/span&gt;&lt;span class="s"&gt;"cambiarValor()"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Actualizar&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nf"&gt;cambiarValor&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;valor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Nuevo&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Esto &lt;strong&gt;siempre actualizará&lt;/strong&gt; la vista, incluso con &lt;code&gt;OnPush&lt;/code&gt;.&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;3️⃣ Uso de &lt;code&gt;async&lt;/code&gt; en un &lt;code&gt;| async&lt;/code&gt; pipe (Observables)&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Si usas el pipe &lt;code&gt;async&lt;/code&gt;, Angular actualizará automáticamente el componente cuando el Observable emita un nuevo valor.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;{{ datos$ | async }}&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;datos$&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;http&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://api.example.com/data&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  &lt;strong&gt;4️⃣ Cambios manuales con &lt;code&gt;markForCheck()&lt;/code&gt;&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Si necesitas actualizar manualmente el componente, puedes usar &lt;code&gt;ChangeDetectorRef.markForCheck()&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;cd&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ChangeDetectorRef&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

&lt;span class="nf"&gt;actualizar&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;valor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Nuevo&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;markForCheck&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// 🔥 Forzar actualización&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  &lt;strong&gt;5️⃣ Cambio en una variable dentro de un &lt;code&gt;setTimeout&lt;/code&gt; o &lt;code&gt;setInterval&lt;/code&gt;&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Si modificamos una variable dentro de &lt;code&gt;setTimeout&lt;/code&gt;, Angular no lo detectará a menos que usemos &lt;code&gt;markForCheck()&lt;/code&gt;.  &lt;/p&gt;

&lt;p&gt;❌ &lt;strong&gt;No se actualiza automáticamente&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nf"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;valor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Nuevo&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="mi"&gt;2000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;✅ &lt;strong&gt;Solución con &lt;code&gt;markForCheck()&lt;/code&gt;&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nf"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;valor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Nuevo&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;markForCheck&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="mi"&gt;2000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  &lt;strong&gt;6️⃣ Cambios después de una petición HTTP manual&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Si asignamos un nuevo valor después de una petición HTTP sin &lt;code&gt;async&lt;/code&gt;, Angular &lt;strong&gt;no lo detectará automáticamente&lt;/strong&gt;.  &lt;/p&gt;

&lt;p&gt;❌ &lt;strong&gt;No se actualiza automáticamente&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;http&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://api.example.com/data&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;valor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;✅ &lt;strong&gt;Solución con &lt;code&gt;markForCheck()&lt;/code&gt;&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;http&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://api.example.com/data&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;valor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;markForCheck&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  &lt;strong&gt;7️⃣ Re-adjuntar la detección de cambios con &lt;code&gt;reattach()&lt;/code&gt;&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Si en algún momento se desactiva la detección de cambios con &lt;code&gt;cd.detach()&lt;/code&gt;, podemos volver a activarla con &lt;code&gt;reattach()&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;detach&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// 🛑 Detiene la detección&lt;/span&gt;
&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reattach&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// 🔄 Reactiva la detección&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  📌 &lt;strong&gt;Resumen final&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Si un componente tiene &lt;code&gt;OnPush&lt;/code&gt;, &lt;strong&gt;solo&lt;/strong&gt; se actualizará cuando ocurra alguno de estos eventos:  &lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Evento&lt;/th&gt;
&lt;th&gt;¿Actualiza con &lt;code&gt;OnPush&lt;/code&gt;?&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Cambio en un &lt;code&gt;@Input()&lt;/code&gt; (nueva referencia)&lt;/td&gt;
&lt;td&gt;✅ Sí&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Evento del DOM (&lt;code&gt;click&lt;/code&gt;, &lt;code&gt;input&lt;/code&gt;, etc.)&lt;/td&gt;
&lt;td&gt;✅ Sí&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;async&lt;/code&gt; pipe con Observables&lt;/td&gt;
&lt;td&gt;✅ Sí&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Uso de &lt;code&gt;markForCheck()&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;✅ Sí&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;setTimeout&lt;/code&gt; o &lt;code&gt;setInterval&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;❌ No (a menos que uses &lt;code&gt;markForCheck()&lt;/code&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;HTTP Request (&lt;code&gt;subscribe()&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;❌ No (a menos que uses &lt;code&gt;markForCheck()&lt;/code&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;detach()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;❌ No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;reattach()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;✅ Sí&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  🎯 &lt;strong&gt;Conclusión&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;🔹 &lt;strong&gt;&lt;code&gt;OnPush&lt;/code&gt; mejora el rendimiento&lt;/strong&gt; porque evita que Angular revise el componente en cada ciclo de cambio.&lt;br&gt;&lt;br&gt;
🔹 &lt;strong&gt;Sin embargo, sigue actualizándose&lt;/strong&gt; en situaciones clave como cambios en &lt;code&gt;@Input&lt;/code&gt;, eventos del DOM o usando &lt;code&gt;markForCheck()&lt;/code&gt;.&lt;br&gt;&lt;br&gt;
🔹 &lt;strong&gt;Si necesitas forzar un cambio manualmente&lt;/strong&gt;, usa &lt;code&gt;markForCheck()&lt;/code&gt; o &lt;code&gt;detectChanges()&lt;/code&gt;.  &lt;/p&gt;

&lt;p&gt;Ahora tienes &lt;strong&gt;el conocimiento completo&lt;/strong&gt; sobre &lt;code&gt;OnPush&lt;/code&gt; y cuándo se actualizan los componentes. 🚀🔥&lt;/p&gt;

</description>
    </item>
    <item>
      <title>🚀 Optimización y mejora de rendimiento en Angular con Change Detection y OnPush</title>
      <dc:creator>Cristian Arieta</dc:creator>
      <pubDate>Tue, 01 Apr 2025 17:23:00 +0000</pubDate>
      <link>https://dev.to/cristian_arieta_7df932e5f/optimizacion-y-mejora-de-rendimiento-en-angular-con-change-detection-y-onpush-2bj0</link>
      <guid>https://dev.to/cristian_arieta_7df932e5f/optimizacion-y-mejora-de-rendimiento-en-angular-con-change-detection-y-onpush-2bj0</guid>
      <description>&lt;h3&gt;
  
  
  &lt;strong&gt;📌 Introducción: ¿Por qué es importante la optimización?&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Cuando creamos aplicaciones en Angular, el rendimiento puede verse afectado si no manejamos correctamente el cambio de estado de los componentes. Esto se debe a que &lt;strong&gt;Angular revisa constantemente los cambios en la interfaz&lt;/strong&gt; para actualizar el DOM de forma eficiente. Sin embargo, esta detección de cambios puede volverse costosa en términos de rendimiento si no la controlamos adecuadamente.  &lt;/p&gt;

&lt;p&gt;Aquí es donde entra en juego el &lt;strong&gt;Change Detection (Detección de Cambios)&lt;/strong&gt; y, más específicamente, la estrategia &lt;strong&gt;OnPush&lt;/strong&gt;.  &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;🎯 &lt;strong&gt;Objetivo de este artículo:&lt;/strong&gt; Entender cómo funciona el Change Detection en Angular y cómo podemos optimizar el rendimiento con OnPush.  &lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  🧐 &lt;strong&gt;¿Qué es Change Detection en Angular?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Change Detection (Detección de Cambios) es el mecanismo que usa Angular para actualizar la interfaz de usuario cuando ocurre un cambio en el estado de la aplicación.  &lt;/p&gt;

&lt;p&gt;📌 &lt;strong&gt;Ejemplo básico&lt;/strong&gt;  &lt;/p&gt;

&lt;p&gt;Cuando el usuario hace clic en un botón y cambia un valor, Angular detecta el cambio y actualiza el DOM:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;{{ contador }}&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;(click)=&lt;/span&gt;&lt;span class="s"&gt;"incrementar()"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Incrementar&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MiComponente&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;contador&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nf"&gt;incrementar&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;contador&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;En este caso, &lt;strong&gt;Angular detecta el cambio en &lt;code&gt;contador&lt;/code&gt; y actualiza la vista automáticamente&lt;/strong&gt;.  &lt;/p&gt;

&lt;h3&gt;
  
  
  🤔 &lt;strong&gt;¿Pero cómo hace Angular para detectar los cambios?&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;🔍 Angular usa un proceso llamado &lt;strong&gt;Zone.js&lt;/strong&gt;, que detecta eventos como:  &lt;/p&gt;

&lt;p&gt;✅ Eventos del usuario (clics, inputs, etc.)&lt;br&gt;&lt;br&gt;
✅ Llamadas a &lt;code&gt;setTimeout&lt;/code&gt; o &lt;code&gt;setInterval&lt;/code&gt;&lt;br&gt;&lt;br&gt;
✅ Peticiones HTTP  &lt;/p&gt;

&lt;p&gt;Cada vez que detecta un cambio, Angular &lt;strong&gt;verifica todos los componentes del árbol&lt;/strong&gt; para ver si algo ha cambiado.  &lt;/p&gt;

&lt;p&gt;⚠️ &lt;strong&gt;Problema:&lt;/strong&gt; Si tenemos muchos componentes y Angular revisa todos en cada cambio, ¡puede volverse lento!  &lt;/p&gt;


&lt;h2&gt;
  
  
  🚀 &lt;strong&gt;¿Cómo optimizamos Change Detection con OnPush?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Por defecto, Angular usa la estrategia &lt;strong&gt;ChangeDetectionStrategy.Default&lt;/strong&gt;, lo que significa que &lt;strong&gt;verifica todos los componentes en cada cambio&lt;/strong&gt;, sin importar si realmente han cambiado.  &lt;/p&gt;

&lt;p&gt;💡 &lt;strong&gt;Aquí es donde entra en juego &lt;code&gt;OnPush&lt;/code&gt;&lt;/strong&gt;  &lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;🛠️ Implementando OnPush en un Componente&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Si queremos mejorar el rendimiento, podemos decirle a Angular:  &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;"Solo verifica este componente si cambia una de sus entradas (&lt;code&gt;@Input&lt;/code&gt;)"&lt;/strong&gt;  &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Esto lo logramos con &lt;strong&gt;ChangeDetectionStrategy.OnPush&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ChangeDetectionStrategy&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Input&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@angular/core&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;app-mi-componente&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;template&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`&amp;lt;p&amp;gt;{{ dato }}&amp;lt;/p&amp;gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;changeDetection&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ChangeDetectionStrategy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;OnPush&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MiComponente&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Input&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="nx"&gt;dato&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;📌 Ahora, este componente &lt;strong&gt;solo se actualizará cuando cambie su &lt;code&gt;@Input&lt;/code&gt;&lt;/strong&gt; y no en cada cambio global.  &lt;/p&gt;




&lt;h2&gt;
  
  
  🛠️ &lt;strong&gt;Ejemplo práctico de OnPush en acción&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Imagina que tenemos una lista de productos en una tienda:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;app-producto&lt;/span&gt; &lt;span class="na"&gt;*ngFor=&lt;/span&gt;&lt;span class="s"&gt;"let p of productos"&lt;/span&gt; &lt;span class="na"&gt;[producto]=&lt;/span&gt;&lt;span class="s"&gt;"p"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/app-producto&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Y el componente &lt;code&gt;ProductoComponent&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;app-producto&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;template&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`&amp;lt;p&amp;gt;{{ producto.nombre }}&amp;lt;/p&amp;gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;changeDetection&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ChangeDetectionStrategy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;OnPush&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ProductoComponent&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Input&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="nx"&gt;producto&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;nombre&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;🔍 Diferencias clave:&lt;/strong&gt;  &lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Estrategia Default&lt;/th&gt;
&lt;th&gt;Estrategia OnPush&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Angular revisa &lt;strong&gt;todos&lt;/strong&gt; los componentes en cada cambio&lt;/td&gt;
&lt;td&gt;Solo revisa el componente si cambia su &lt;code&gt;@Input&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Puede causar ralentizaciones en grandes aplicaciones&lt;/td&gt;
&lt;td&gt;Mejora el rendimiento significativamente&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  🛠️ &lt;strong&gt;Cómo forzar detección de cambios con OnPush&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Si usamos &lt;code&gt;OnPush&lt;/code&gt;, Angular &lt;strong&gt;no actualizará el componente automáticamente&lt;/strong&gt; a menos que cambie su &lt;code&gt;@Input&lt;/code&gt;.  &lt;/p&gt;

&lt;p&gt;📌 ¿Pero qué pasa si queremos actualizarlo manualmente?  &lt;/p&gt;

&lt;p&gt;Podemos usar &lt;code&gt;ChangeDetectorRef.markForCheck()&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ChangeDetectorRef&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@angular/core&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;app-mi-componente&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;template&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`&amp;lt;p&amp;gt;{{ mensaje }}&amp;lt;/p&amp;gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;changeDetection&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ChangeDetectionStrategy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;OnPush&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MiComponente&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;mensaje&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Hola Mundo&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;cd&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ChangeDetectorRef&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

  &lt;span class="nf"&gt;cambiarMensaje&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;mensaje&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Nuevo Mensaje&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;markForCheck&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// 🔥 Forzar actualización&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;✅ &lt;code&gt;markForCheck()&lt;/code&gt; indica a Angular que &lt;strong&gt;verifique este componente en la próxima detección de cambios&lt;/strong&gt;.  &lt;/p&gt;

&lt;p&gt;Si queremos &lt;strong&gt;detener la detección de cambios por completo&lt;/strong&gt;, podemos usar &lt;code&gt;detach()&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;detach&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// 🛑 Detiene la detección de cambios&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Para volver a activarla:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reattach&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🎯 &lt;strong&gt;¿Cuándo usar OnPush?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;📌 &lt;strong&gt;Úsalo cuando...&lt;/strong&gt;  &lt;/p&gt;

&lt;p&gt;✅ Tienes listas grandes de elementos en &lt;code&gt;ngFor&lt;/code&gt;&lt;br&gt;&lt;br&gt;
✅ Quieres mejorar el rendimiento de componentes que no cambian frecuentemente&lt;br&gt;&lt;br&gt;
✅ Estás trabajando con datos que solo se actualizan desde el servidor  &lt;/p&gt;

&lt;p&gt;📌 &lt;strong&gt;No lo uses cuando...&lt;/strong&gt;  &lt;/p&gt;

&lt;p&gt;❌ Necesitas detectar cambios en variables locales sin &lt;code&gt;@Input&lt;/code&gt;&lt;br&gt;&lt;br&gt;
❌ Dependencias internas del componente cambian constantemente  &lt;/p&gt;




&lt;h2&gt;
  
  
  🏁 &lt;strong&gt;Conclusión: ¡Optimiza tu Angular como un Pro!&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;💡 El sistema de detección de cambios de Angular es poderoso, pero puede ser &lt;strong&gt;costoso&lt;/strong&gt; si no lo manejamos bien.  &lt;/p&gt;

&lt;p&gt;🚀 &lt;strong&gt;OnPush es la clave&lt;/strong&gt; para mejorar el rendimiento en componentes que dependen de datos externos.  &lt;/p&gt;

&lt;p&gt;🔥 &lt;strong&gt;Recapitulación rápida:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
✅ &lt;code&gt;ChangeDetectionStrategy.Default&lt;/code&gt; revisa TODO en cada cambio 🔄&lt;br&gt;&lt;br&gt;
✅ &lt;code&gt;ChangeDetectionStrategy.OnPush&lt;/code&gt; revisa SOLO cuando cambia un &lt;code&gt;@Input&lt;/code&gt; 🚀&lt;br&gt;&lt;br&gt;
✅ Podemos forzar actualizaciones con &lt;code&gt;markForCheck()&lt;/code&gt; 🔥&lt;br&gt;&lt;br&gt;
✅ Podemos detener detecciones con &lt;code&gt;detach()&lt;/code&gt; 🛑  &lt;/p&gt;

&lt;p&gt;Ahora que lo sabes, ¡aplícalo y haz que tus aplicaciones sean &lt;strong&gt;rápidas como un rayo!&lt;/strong&gt; ⚡🚀  &lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;¿Qué te pareció esta explicación?&lt;/strong&gt; 🤔
&lt;/h3&gt;

&lt;p&gt;Si tienes alguna duda o quieres más ejemplos, dime y seguimos aprendiendo juntos. ¡Nos vemos en el próximo artículo, Master! 😎🚀&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>angular</category>
      <category>typescript</category>
      <category>workplace</category>
    </item>
    <item>
      <title>🚀 Diferencias entre *ngIf y ngSwitch en Angular</title>
      <dc:creator>Cristian Arieta</dc:creator>
      <pubDate>Tue, 01 Apr 2025 12:23:00 +0000</pubDate>
      <link>https://dev.to/cristian_arieta_7df932e5f/diferencias-entre-ngif-y-ngswitch-en-angular-1fcn</link>
      <guid>https://dev.to/cristian_arieta_7df932e5f/diferencias-entre-ngif-y-ngswitch-en-angular-1fcn</guid>
      <description>&lt;p&gt;Cuando trabajamos con Angular en la capa de presentación (HTML), es común necesitar mostrar u ocultar elementos dinámicamente según una condición. Para esto, Angular nos proporciona dos estructuras de control poderosas: &lt;code&gt;*ngIf&lt;/code&gt; y &lt;code&gt;ngSwitch&lt;/code&gt;. Aunque ambas sirven para manejar la visualización condicional, tienen diferencias clave en su funcionamiento y en los escenarios donde se recomienda usar cada una.&lt;/p&gt;

&lt;h2&gt;
  
  
  🔍 1. ¿Qué es &lt;code&gt;*ngIf&lt;/code&gt; y cómo funciona?
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;*ngIf&lt;/code&gt; es una directiva estructural que permite renderizar o eliminar elementos del DOM según una condición booleana. Si la condición es &lt;code&gt;true&lt;/code&gt;, el elemento se muestra; si es &lt;code&gt;false&lt;/code&gt;, el elemento se elimina completamente del DOM.&lt;/p&gt;

&lt;h3&gt;
  
  
  ✅ Ejemplo de uso:
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;*ngIf=&lt;/span&gt;&lt;span class="s"&gt;"mostrarMensaje"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;📢 Este mensaje se muestra si `mostrarMensaje` es verdadero.&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;En este caso, si &lt;code&gt;mostrarMensaje&lt;/code&gt; es &lt;code&gt;true&lt;/code&gt;, el párrafo se mostrará; si es &lt;code&gt;false&lt;/code&gt;, el elemento ni siquiera existirá en el DOM.&lt;/p&gt;

&lt;h3&gt;
  
  
  🎯 Ventajas de &lt;code&gt;*ngIf&lt;/code&gt;:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;🔹 Remueve completamente el elemento del DOM cuando la condición es &lt;code&gt;false&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;🔹 Ideal para elementos que solo se necesitan en ciertas condiciones.&lt;/li&gt;
&lt;li&gt;🔹 Mejora el rendimiento si el contenido es pesado, ya que no se renderiza innecesariamente.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  ⚠️ Desventajas de &lt;code&gt;*ngIf&lt;/code&gt;:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;🔸 Si se usa con contenido pesado, al cambiar la condición a &lt;code&gt;true&lt;/code&gt; puede haber un pequeño retraso en la re-renderización.&lt;/li&gt;
&lt;li&gt;🔸 No es eficiente si se usa para cambiar entre múltiples opciones, ya que requiere múltiples verificaciones.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🔍 2. ¿Qué es &lt;code&gt;ngSwitch&lt;/code&gt; y cómo funciona?
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;ngSwitch&lt;/code&gt; es otra directiva estructural que permite alternar entre múltiples opciones. Es similar a &lt;code&gt;switch&lt;/code&gt; en TypeScript, donde un valor determina cuál de varias opciones se renderiza.&lt;/p&gt;

&lt;h3&gt;
  
  
  ✅ Ejemplo de uso:
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;[ngSwitch]=&lt;/span&gt;&lt;span class="s"&gt;"estado"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;*ngSwitchCase=&lt;/span&gt;&lt;span class="s"&gt;"'iniciado'"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;🚀 El proceso ha iniciado.&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;*ngSwitchCase=&lt;/span&gt;&lt;span class="s"&gt;"'en_progreso'"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;⏳ El proceso está en progreso.&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;*ngSwitchCase=&lt;/span&gt;&lt;span class="s"&gt;"'completado'"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;✅ El proceso se ha completado.&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;*ngSwitchDefault&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;⚠️ Estado desconocido.&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  🎯 Ventajas de &lt;code&gt;ngSwitch&lt;/code&gt;:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;🔹 Más organizado cuando hay múltiples condiciones.&lt;/li&gt;
&lt;li&gt;🔹 Evita el anidamiento excesivo de &lt;code&gt;*ngIf&lt;/code&gt;, haciendo el código más limpio.&lt;/li&gt;
&lt;li&gt;🔹 Mejora la legibilidad cuando hay más de dos condiciones posibles.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  ⚠️ Desventajas de &lt;code&gt;ngSwitch&lt;/code&gt;:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;🔸 Todos los casos se evalúan, aunque solo uno se muestre.&lt;/li&gt;
&lt;li&gt;🔸 No es ideal si solo hay dos condiciones (para esto es mejor &lt;code&gt;*ngIf&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  ⚖️ 3. Comparación entre &lt;code&gt;*ngIf&lt;/code&gt; y &lt;code&gt;ngSwitch&lt;/code&gt;
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Característica&lt;/th&gt;
&lt;th&gt;&lt;code&gt;*ngIf&lt;/code&gt;&lt;/th&gt;
&lt;th&gt;&lt;code&gt;ngSwitch&lt;/code&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;📌 Condición&lt;/td&gt;
&lt;td&gt;Booleano (true/false)&lt;/td&gt;
&lt;td&gt;Múltiples valores posibles&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;🗑️ Eliminación del DOM&lt;/td&gt;
&lt;td&gt;Sí, cuando la condición es &lt;code&gt;false&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Sí, pero mantiene la evaluación de todas las opciones&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;🔄 Uso recomendado&lt;/td&gt;
&lt;td&gt;Mostrar u ocultar elementos dinámicamente&lt;/td&gt;
&lt;td&gt;Alternar entre múltiples opciones&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;⚡ Eficiencia&lt;/td&gt;
&lt;td&gt;Mejor si solo hay una o dos condiciones&lt;/td&gt;
&lt;td&gt;Mejor si hay más de dos opciones&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  🛠️ 4. Uso en TypeScript
&lt;/h2&gt;

&lt;p&gt;En Angular, tanto &lt;code&gt;*ngIf&lt;/code&gt; como &lt;code&gt;ngSwitch&lt;/code&gt; dependen de variables de TypeScript para evaluar sus condiciones. Por ejemplo, en el componente:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AppComponent&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;mostrarMensaje&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;estado&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;en_progreso&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;🔹 &lt;code&gt;mostrarMensaje&lt;/code&gt; controla la visibilidad del elemento con &lt;code&gt;*ngIf&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;🔹 &lt;code&gt;estado&lt;/code&gt; define qué opción se muestra en &lt;code&gt;ngSwitch&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🤔 5. ¿Cuándo usar cada uno?
&lt;/h2&gt;

&lt;p&gt;✅ &lt;strong&gt;Usa &lt;code&gt;*ngIf&lt;/code&gt; cuando solo hay dos opciones&lt;/strong&gt; (mostrar u ocultar un elemento).&lt;br&gt;&lt;br&gt;
✅ &lt;strong&gt;Usa &lt;code&gt;ngSwitch&lt;/code&gt; cuando hay múltiples opciones posibles&lt;/strong&gt; y solo una debe mostrarse.&lt;/p&gt;
&lt;h3&gt;
  
  
  📝 Ejemplo práctico:
&lt;/h3&gt;

&lt;p&gt;Supongamos que queremos mostrar un mensaje de estado de una tarea:&lt;/p&gt;

&lt;p&gt;🔹 &lt;strong&gt;Con &lt;code&gt;*ngIf&lt;/code&gt;&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;*ngIf=&lt;/span&gt;&lt;span class="s"&gt;"estado === 'completado'"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;✔️ Tarea completada&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;*ngIf=&lt;/span&gt;&lt;span class="s"&gt;"estado === 'pendiente'"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;⌛ Tarea pendiente&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;🔹 &lt;strong&gt;Con &lt;code&gt;ngSwitch&lt;/code&gt;&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;[ngSwitch]=&lt;/span&gt;&lt;span class="s"&gt;"estado"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;*ngSwitchCase=&lt;/span&gt;&lt;span class="s"&gt;"'completado'"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;✔️ Tarea completada&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;*ngSwitchCase=&lt;/span&gt;&lt;span class="s"&gt;"'pendiente'"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;⌛ Tarea pendiente&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;*ngSwitchDefault&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;⚠️ Estado desconocido&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;📌 &lt;strong&gt;Si solo hay dos opciones&lt;/strong&gt;, &lt;code&gt;*ngIf&lt;/code&gt; es más eficiente.&lt;br&gt;&lt;br&gt;
📌 &lt;strong&gt;Si hay más de dos opciones&lt;/strong&gt;, &lt;code&gt;ngSwitch&lt;/code&gt; es más legible.&lt;/p&gt;




&lt;h2&gt;
  
  
  🎯 Conclusión
&lt;/h2&gt;

&lt;p&gt;Tanto &lt;code&gt;*ngIf&lt;/code&gt; como &lt;code&gt;ngSwitch&lt;/code&gt; son herramientas poderosas en Angular, pero deben usarse según el escenario adecuado.&lt;br&gt;&lt;br&gt;
✅ &lt;code&gt;*ngIf&lt;/code&gt; es ideal para condiciones simples donde un elemento debe mostrarse o desaparecer completamente del DOM.&lt;br&gt;&lt;br&gt;
✅ &lt;code&gt;ngSwitch&lt;/code&gt; es mejor cuando hay múltiples opciones y solo una debe mostrarse.  &lt;/p&gt;

&lt;p&gt;⚡ &lt;strong&gt;Usar la opción correcta puede hacer que tu código sea más eficiente, limpio y mantenible.&lt;/strong&gt; 🚀&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>angular</category>
      <category>cucle</category>
      <category>typescript</category>
    </item>
    <item>
      <title>Explorando las Rutas en Angular: Cómo navegar por tu aplicación</title>
      <dc:creator>Cristian Arieta</dc:creator>
      <pubDate>Mon, 31 Mar 2025 21:04:00 +0000</pubDate>
      <link>https://dev.to/cristian_arieta_7df932e5f/explorando-las-rutas-en-angular-como-navegar-por-tu-aplicacion-21bh</link>
      <guid>https://dev.to/cristian_arieta_7df932e5f/explorando-las-rutas-en-angular-como-navegar-por-tu-aplicacion-21bh</guid>
      <description>&lt;p&gt;¡Bienvenidos a este tutorial sobre rutas en Angular! 🌍 Si alguna vez has creado una aplicación web, seguramente sabes lo importante que es la navegación. En Angular, las rutas nos permiten navegar de una página a otra sin tener que recargar toda la página, lo que hace que la experiencia del usuario sea mucho más fluida. Hoy, vamos a explorar cómo funcionan las rutas en Angular y cómo podemos usarlas para navegar entre diferentes componentes, tanto con parámetros básicos como avanzados. ¡Vamos allá! 🚀&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;¿Qué son las Rutas en Angular?&lt;/strong&gt; 🤔
&lt;/h3&gt;

&lt;p&gt;Las rutas en Angular permiten definir las distintas "páginas" o "vistas" dentro de una aplicación de una sola página (SPA). En lugar de recargar toda la página cada vez que el usuario navega, Angular solo cambia el componente que se debe mostrar en función de la URL.&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;Configurar Rutas Básicas&lt;/strong&gt; 🛣️
&lt;/h3&gt;

&lt;p&gt;Para empezar, vamos a configurar algunas rutas básicas en nuestra aplicación Angular. Vamos a ver cómo hacerlo paso a paso.&lt;/p&gt;

&lt;h4&gt;
  
  
  Paso 1: Definir las rutas en &lt;code&gt;app-routing.module.ts&lt;/code&gt;
&lt;/h4&gt;

&lt;p&gt;Este es el archivo donde configuramos todas nuestras rutas. Cada ruta debe tener un &lt;code&gt;path&lt;/code&gt; (la URL a la que queremos acceder) y un &lt;code&gt;component&lt;/code&gt; (el componente que se debe mostrar cuando el usuario navega a esa URL).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;NgModule&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@angular/core&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;RouterModule&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Routes&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@angular/router&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;HomeComponent&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./home/home.component&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;AboutComponent&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./about/about.component&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;routes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Routes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;component&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;HomeComponent&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="c1"&gt;// Página de inicio&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;about&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;component&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;AboutComponent&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="c1"&gt;// Página de "Sobre nosotros"&lt;/span&gt;
&lt;span class="p"&gt;];&lt;/span&gt;

&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;NgModule&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;imports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;RouterModule&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forRoot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;routes&lt;/span&gt;&lt;span class="p"&gt;)],&lt;/span&gt;
  &lt;span class="na"&gt;exports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;RouterModule&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AppRoutingModule&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;En este ejemplo, hemos creado dos rutas:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;path: ''&lt;/code&gt; — La página de inicio, que es lo que se muestra cuando visitamos la raíz de la aplicación.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;path: 'about'&lt;/code&gt; — La página de "Sobre nosotros", que se accede con &lt;code&gt;/about&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  Paso 2: Usar el &lt;code&gt;router-outlet&lt;/code&gt;
&lt;/h4&gt;

&lt;p&gt;El siguiente paso es asegurarnos de que tenemos un lugar donde las rutas se rendericen en el DOM. Esto se hace usando la directiva &lt;code&gt;router-outlet&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;En nuestro &lt;code&gt;app.component.html&lt;/code&gt;, agregamos lo siguiente:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;router-outlet&amp;gt;&amp;lt;/router-outlet&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Este es el espacio donde los componentes se mostrarán según la ruta seleccionada.&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;Navegación entre Rutas&lt;/strong&gt; 🧭
&lt;/h3&gt;

&lt;p&gt;Ahora que tenemos nuestras rutas configuradas, ¿cómo navegamos entre ellas? Angular tiene una directiva llamada &lt;code&gt;routerLink&lt;/code&gt;, que nos permite crear enlaces para navegar entre las páginas.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;routerLink=&lt;/span&gt;&lt;span class="s"&gt;"/"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Inicio&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;routerLink=&lt;/span&gt;&lt;span class="s"&gt;"/about"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Sobre nosotros&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Cada vez que el usuario haga clic en uno de estos enlaces, Angular cambiará la vista sin recargar la página.&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;Rutas con Parámetros&lt;/strong&gt; 🔑
&lt;/h3&gt;

&lt;p&gt;A veces necesitamos pasar información de una ruta a otra. Esto se puede hacer fácilmente con los parámetros de ruta.&lt;/p&gt;

&lt;h4&gt;
  
  
  Parámetros Básicos
&lt;/h4&gt;

&lt;p&gt;Supongamos que tenemos una página de detalle de un producto. Queremos que la URL incluya el ID del producto para que podamos cargar los datos del producto correspondiente.&lt;/p&gt;

&lt;h5&gt;
  
  
  Paso 1: Definir la ruta con un parámetro
&lt;/h5&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;routes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Routes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;product/:id&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;component&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ProductDetailComponent&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Aquí, &lt;code&gt;:id&lt;/code&gt; es un parámetro que representará el ID del producto en la URL. Por ejemplo, &lt;code&gt;product/123&lt;/code&gt; cargará el detalle del producto con el ID 123.&lt;/p&gt;

&lt;h5&gt;
  
  
  Paso 2: Acceder al parámetro en el componente
&lt;/h5&gt;

&lt;p&gt;Dentro de &lt;code&gt;ProductDetailComponent&lt;/code&gt;, podemos acceder al parámetro &lt;code&gt;id&lt;/code&gt; de la siguiente manera:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ActivatedRoute&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@angular/router&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;app-product-detail&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;templateUrl&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./product-detail.component.html&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;styleUrls&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./product-detail.component.css&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ProductDetailComponent&lt;/span&gt; &lt;span class="k"&gt;implements&lt;/span&gt; &lt;span class="nx"&gt;OnInit&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;productId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;route&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ActivatedRoute&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

  &lt;span class="nf"&gt;ngOnInit&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;productId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;route&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;snapshot&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;paramMap&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;id&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;En este caso, &lt;code&gt;this.route.snapshot.paramMap.get('id')&lt;/code&gt; nos da el valor del parámetro &lt;code&gt;id&lt;/code&gt; que se pasa en la URL.&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;Rutas Avanzadas con Query Parameters&lt;/strong&gt; 🔍
&lt;/h3&gt;

&lt;p&gt;Los &lt;strong&gt;Query Parameters&lt;/strong&gt; nos permiten pasar información adicional en la URL de una manera más flexible. A diferencia de los parámetros de ruta, estos no forman parte de la estructura principal de la URL.&lt;/p&gt;

&lt;h4&gt;
  
  
  Paso 1: Definir la ruta con query parameters
&lt;/h4&gt;

&lt;p&gt;Supongamos que queremos pasar un filtro de búsqueda como parámetro. La URL podría verse así: &lt;code&gt;products?category=electronics&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;routes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Routes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;products&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;component&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ProductListComponent&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Paso 2: Acceder a los query parameters
&lt;/h4&gt;

&lt;p&gt;Para acceder a los query parameters, usamos el &lt;code&gt;ActivatedRoute&lt;/code&gt; de manera similar a como accedemos a los parámetros de ruta, pero en este caso, debemos usar &lt;code&gt;queryParamMap&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ActivatedRoute&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@angular/router&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;app-product-list&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;templateUrl&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./product-list.component.html&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;styleUrls&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./product-list.component.css&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ProductListComponent&lt;/span&gt; &lt;span class="k"&gt;implements&lt;/span&gt; &lt;span class="nx"&gt;OnInit&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;category&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;route&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ActivatedRoute&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

  &lt;span class="nf"&gt;ngOnInit&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;route&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;queryParamMap&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;category&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;category&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  &lt;strong&gt;Redirección y Rutas Protegidas&lt;/strong&gt; 🚨
&lt;/h3&gt;

&lt;p&gt;Las rutas también pueden redirigir automáticamente a los usuarios si no tienen acceso a ciertas páginas o si no están autenticados. Para ello, usamos las &lt;strong&gt;guardias de ruta&lt;/strong&gt; (&lt;code&gt;CanActivate&lt;/code&gt;, &lt;code&gt;CanLoad&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;Por ejemplo, si queremos proteger una página de administrador:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;routes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Routes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;admin&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;component&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;AdminComponent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;canActivate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;AuthGuard&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;El &lt;code&gt;AuthGuard&lt;/code&gt; verifica si el usuario está autenticado. Si no lo está, lo redirige a la página de inicio de sesión.&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;Conclusión&lt;/strong&gt; 🎉
&lt;/h3&gt;

&lt;p&gt;Las rutas son un componente clave para cualquier aplicación web moderna. Nos permiten navegar entre diferentes vistas sin recargar toda la página, hacer aplicaciones más rápidas y crear experiencias más fluidas. Y ahora, con los parámetros de ruta y los query parameters, puedes hacer que tus rutas sean aún más dinámicas y flexibles. ¡Ahora es tu turno de experimentar y crear aplicaciones con rutas en Angular!&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
