Renderizado condicional con @switch

Intermedio
Angular
Angular
Actualizado: 24/09/2025

Sintaxis @switch y @case

La directiva @switch representa la evolución moderna del renderizado condicional múltiple en Angular. Esta sintaxis, introducida en Angular 17 y estabilizada desde Angular 18, reemplaza completamente la antigua directiva *ngSwitch ofreciendo un enfoque más limpio y eficiente.

La estructura básica de @switch sigue un patrón familiar para quienes conocen las declaraciones switch de JavaScript o TypeScript, pero adaptado específicamente para templates de Angular:

@switch (expresion) {
  @case (valor1) {
    <!-- Contenido cuando expresion === valor1 -->
  }
  @case (valor2) {
    <!-- Contenido cuando expresion === valor2 -->
  }
  @default {
    <!-- Contenido por defecto -->
  }
}

Anatomía de la sintaxis

La directiva @switch evalúa una expresión y renderiza el contenido del @case correspondiente que coincida con el valor. Cada caso debe contener un valor único y específico para la comparación.

Veamos un ejemplo práctico con el estado de un pedido:

@switch (estadoPedido) {
  @case ('pendiente') {
    <div class="estado-pendiente">
      <p>Tu pedido está pendiente de procesamiento</p>
      <span class="icono">⏳</span>
    </div>
  }
  @case ('enviado') {
    <div class="estado-enviado">
      <p>Tu pedido ha sido enviado</p>
      <span class="icono">🚚</span>
    </div>
  }
  @case ('entregado') {
    <div class="estado-entregado">
      <p>Tu pedido ha sido entregado</p>
      <span class="icono">✅</span>
    </div>
  }
  @default {
    <div class="estado-desconocido">
      <p>Estado del pedido no disponible</p>
    </div>
  }
}

Bloque @default

El bloque @default actúa como el caso por defecto cuando ninguno de los @case coincide con la expresión evaluada. Su uso es opcional, pero recomendado para manejar valores inesperados:

@switch (tipoUsuario) {
  @case ('admin') {
    <button class="btn-admin">Panel de Administración</button>
  }
  @case ('editor') {
    <button class="btn-editor">Crear Contenido</button>
  }
  @case ('viewer') {
    <button class="btn-viewer">Ver Contenido</button>
  }
  @default {
    <p>Tipo de usuario no reconocido</p>
  }
}

Comparación por identidad estricta

La directiva @switch utiliza comparación por identidad estricta (===), lo que significa que tanto el valor como el tipo deben coincidir exactamente. Esto es importante cuando trabajamos con diferentes tipos de datos:

<!-- En el componente -->
export class MiComponente {
  numero = 1;
  texto = '1';
}
<!-- En el template -->
@switch (numero) {
  @case (1) {
    <p>Número uno</p> <!-- ✅ Se renderiza -->
  }
  @case ('1') {
    <p>String uno</p> <!-- ❌ No se renderiza -->
  }
}

Sintaxis con expresiones del componente

Los casos pueden utilizar propiedades del componente para realizar comparaciones dinámicas:

export class ComponenteEstados {
  ESTADO_ACTIVO = 'activo';
  ESTADO_INACTIVO = 'inactivo';
  ESTADO_PENDIENTE = 'pendiente';
  
  estadoActual = 'activo';
}
@switch (estadoActual) {
  @case (ESTADO_ACTIVO) {
    <div class="badge-activo">Activo</div>
  }
  @case (ESTADO_INACTIVO) {
    <div class="badge-inactivo">Inactivo</div>
  }
  @case (ESTADO_PENDIENTE) {
    <div class="badge-pendiente">Pendiente</div>
  }
}

Ventajas sobre la sintaxis anterior

La nueva sintaxis @switch ofrece varias mejoras significativas respecto a *ngSwitch:

  • Mayor legibilidad: La estructura es más clara y fácil de seguir
  • Mejor rendimiento: Optimizaciones internas del compilador de Angular
  • Sintaxis más natural: Similar a las declaraciones switch de TypeScript
  • Menos verbosidad: No requiere directivas adicionales como *ngSwitchCase

La migración desde *ngSwitch es directa, pero la nueva sintaxis representa una mejora sustancial en la experiencia de desarrollo y el rendimiento de la aplicación.

Comparaciones múltiples

La directiva @switch demuestra su verdadero valor cuando necesitamos manejar diferentes tipos de datos y múltiples condiciones de forma eficiente. A diferencia de las cadenas de @if consecutivos, @switch ofrece una solución más limpia y optimizada para escenarios con múltiples comparaciones.

Trabajando con diferentes tipos de datos

Una de las ventajas de @switch es su capacidad para manejar distintos tipos de datos de manera consistente. Veamos ejemplos prácticos con strings, números y enumeraciones:

Ejemplo con strings - Sistema de roles:

export class UsuarioComponent {
  rolUsuario: string = 'moderador';
}
@switch (rolUsuario) {
  @case ('admin') {
    <div class="panel-admin">
      <h3>Panel de Administración</h3>
      <button>Gestionar usuarios</button>
      <button>Configuración del sistema</button>
    </div>
  }
  @case ('moderador') {
    <div class="panel-moderador">
      <h3>Panel de Moderación</h3>
      <button>Revisar contenido</button>
      <button>Gestionar comentarios</button>
    </div>
  }
  @case ('usuario') {
    <div class="panel-usuario">
      <h3>Mi perfil</h3>
      <button>Editar datos</button>
    </div>
  }
  @default {
    <div class="acceso-denegado">
      <p>Rol no reconocido</p>
    </div>
  }
}

Ejemplo con números - Niveles de experiencia:

export class JuegoComponent {
  nivelJugador: number = 25;
}
@switch (Math.floor(nivelJugador / 10)) {
  @case (0) {
    <div class="nivel-principiante">
      <span class="badge">Principiante</span>
      <p>Nivel 1-9: ¡Sigue practicando!</p>
    </div>
  }
  @case (1) {
    <div class="nivel-intermedio">
      <span class="badge">Intermedio</span>
      <p>Nivel 10-19: Buen progreso</p>
    </div>
  }
  @case (2) {
    <div class="nivel-avanzado">
      <span class="badge">Avanzado</span>
      <p>Nivel 20-29: ¡Excelente!</p>
    </div>
  }
  @default {
    <div class="nivel-experto">
      <span class="badge">Experto</span>
      <p>Nivel 30+: ¡Eres un maestro!</p>
    </div>
  }
}

Uso con enumeraciones TypeScript

Los enums son especialmente útiles con @switch porque proporcionan type safety y mejor mantenibilidad del código:

export enum EstadoConexion {
  DESCONECTADO = 'desconectado',
  CONECTANDO = 'conectando',
  CONECTADO = 'conectado',
  ERROR = 'error'
}

export class ConexionComponent {
  estado = EstadoConexion.CONECTANDO;
}
@switch (estado) {
  @case (EstadoConexion.DESCONECTADO) {
    <div class="estado-offline">
      <span class="indicador rojo"></span>
      <p>Sin conexión</p>
      <button (click)="conectar()">Conectar</button>
    </div>
  }
  @case (EstadoConexion.CONECTANDO) {
    <div class="estado-conectando">
      <span class="indicador amarillo pulsante"></span>
      <p>Conectando...</p>
    </div>
  }
  @case (EstadoConexion.CONECTADO) {
    <div class="estado-online">
      <span class="indicador verde"></span>
      <p>Conectado exitosamente</p>
    </div>
  }
  @case (EstadoConexion.ERROR) {
    <div class="estado-error">
      <span class="indicador rojo"></span>
      <p>Error de conexión</p>
      <button (click)="reintentar()">Reintentar</button>
    </div>
  }
}

Comparaciones con valores booleanos

Aunque menos común, @switch también puede manejar valores booleanos de forma efectiva:

export class NotificacionComponent {
  notificacionesActivas = true;
  modoOscuro = false;
}
@switch (notificacionesActivas) {
  @case (true) {
    <div class="notificaciones-on">
      <p>Notificaciones activadas</p>
      <span class="icono">🔔</span>
    </div>
  }
  @case (false) {
    <div class="notificaciones-off">
      <p>Notificaciones desactivadas</p>
      <span class="icono">🔕</span>
    </div>
  }
}

Cuándo usar @switch vs múltiples @if

La elección entre @switch y múltiples @if depende del escenario específico:

Usa @switch cuando:

  • Comparas una sola variable contra múltiples valores específicos
  • Los valores son mutuamente excluyentes
  • Tienes 3 o más condiciones relacionadas
  • Necesitas un caso por defecto claro

Usa múltiples @if cuando:

  • Comparas diferentes variables o expresiones complejas
  • Las condiciones no son mutuamente excluyentes
  • Necesitas lógica compleja en las condiciones
  • Tienes pocas condiciones (1-2)

Ejemplo comparativo - Mejor con @switch:

<!-- ✅ Recomendado: @switch para una variable, múltiples valores -->
@switch (tipoAlerta) {
  @case ('info') { <div class="alert-info">Información</div> }
  @case ('warning') { <div class="alert-warning">Advertencia</div> }
  @case ('error') { <div class="alert-error">Error</div> }
  @case ('success') { <div class="alert-success">Éxito</div> }
}

<!-- ❌ Menos eficiente: múltiples @if para la misma variable -->
@if (tipoAlerta === 'info') {
  <div class="alert-info">Información</div>
} @else if (tipoAlerta === 'warning') {
  <div class="alert-warning">Advertencia</div>
} @else if (tipoAlerta === 'error') {
  <div class="alert-error">Error</div>
} @else if (tipoAlerta === 'success') {
  <div class="alert-success">Éxito</div>
}

Ejemplo comparativo - Mejor con @if:

<!-- ✅ Recomendado: @if para condiciones diferentes -->
@if (usuario.esAdmin && configuracion.mostrarPanel) {
  <div>Panel de administración</div>
}
@if (notificaciones.nuevas > 0) {
  <div>Tienes {{ notificaciones.nuevas }} mensajes</div>
}
@if (sesion.expiraSoon) {
  <div>Tu sesión expirará pronto</div>
}

Optimización de rendimiento

Angular optimiza internamente las directivas @switch, realizando una sola evaluación de la expresión y comparándola eficientemente con todos los casos. Esto resulta en mejor rendimiento que múltiples evaluaciones @if consecutivas para la misma variable.

La nueva sintaxis de control de flujo también permite al compilador de Angular generar código más eficiente, reduciendo el overhead en tiempo de ejecución y mejorando la experiencia del usuario final.

Fuentes y referencias

Documentación oficial y recursos externos para profundizar en Angular

Documentación oficial de Angular
Alan Sastre - Autor del tutorial

Alan Sastre

Ingeniero de Software y formador, CEO en CertiDevs

Ingeniero de software especializado en Full Stack y en Inteligencia Artificial. Como CEO de CertiDevs, Angular es una de sus áreas de expertise. Con más de 15 años programando, 6K seguidores en LinkedIn y experiencia como formador, Alan se dedica a crear contenido educativo de calidad para desarrolladores de todos los niveles.

Más tutoriales de Angular

Explora más contenido relacionado con Angular y continúa aprendiendo con nuestros tutoriales gratuitos.

Aprendizajes de esta lección

  • Comprender la sintaxis y estructura básica de la directiva @switch y @case en Angular.
  • Aprender a utilizar el bloque @default para manejar casos no contemplados.
  • Diferenciar cuándo usar @switch frente a múltiples directivas @if.
  • Aplicar @switch con distintos tipos de datos, incluyendo strings, números y enums.
  • Conocer las ventajas de rendimiento y legibilidad que ofrece la nueva sintaxis sobre *ngSwitch.