Skip to content

switchMap - Cancelar el Observable anterior y cambiar al más reciente

El operador switchMap genera un nuevo Observable para cada valor del stream de entrada, cancela el Observable anterior y cambia solo al Observable más reciente. Es óptimo para casos como formularios de búsqueda donde solo quieres que la entrada más reciente sea válida.

🔰 Sintaxis básica y uso

ts
import { of } from 'rxjs';
import { delay, switchMap } from 'rxjs';

of('A', 'B', 'C').pipe(
  switchMap(value =>
    of(`${value} completado`).pipe(delay(1000))
  )
).subscribe(console.log);

// Ejemplo de salida:
// C completado
  • Crea un nuevo Observable para cada valor.
  • Sin embargo, cuando llega un nuevo valor, el Observable anterior se cancela.
  • Finalmente, solo se emite C.

🌐 Documentación Oficial RxJS - switchMap

💡 Patrones de uso típicos

  • Autocompletado de formularios de entrada
  • Funcionalidad de búsqueda en vivo (solo la entrada más reciente es válida)
  • Carga de recursos al cambiar navegación o enrutamiento
  • Cuando quieres cambiar las acciones del usuario a la más reciente

🧠 Ejemplo de código práctico (con UI)

Cuando escribes caracteres en el cuadro de búsqueda, se envía inmediatamente una solicitud API y solo se muestra el resultado de lo último ingresado.

ts
import { fromEvent } from 'rxjs';
import { debounceTime, map, switchMap } from 'rxjs';
import { ajax } from 'rxjs/ajax';
import { of } from 'rxjs';

// Crear campo de entrada
const searchInput = document.createElement('input');
searchInput.placeholder = 'Buscar por nombre de usuario';
document.body.appendChild(searchInput);

// Área de salida
const output = document.createElement('div');
output.style.marginTop = '10px';
document.body.appendChild(output);

// Procesamiento de eventos de entrada
fromEvent(searchInput, 'input').pipe(
  debounceTime(300),
  map(event => (event.target as HTMLInputElement).value.trim()),
  switchMap(term => {
    if (term === '') {
      return of([]);
    }
    return ajax.getJSON(`https://jsonplaceholder.typicode.com/users?username_like=${term}`);
  })
).subscribe(users => {
  output.innerHTML = '';

  (users as any[]).forEach(user => {
    const div = document.createElement('div');
    div.textContent = user.username;
    output.appendChild(div);
  });
});
  • Cada vez que cambia la entrada, la solicitud anterior se cancela.
  • Solo se muestran los usuarios que coinciden con la palabra de búsqueda más reciente.

Publicado bajo licencia CC-BY-4.0.