# Introducción

RxJS es una biblioteca para componer programas asíncronos y basados en eventos, mediante secuencias observables. Proporciona un tipo *core*, el Observable, varios tipos satélite (Observer, Schedulers, Subjects) y operadores inspirados por las [funciones de Array](https://developer.mozilla.org/en-US/docs/Archive/Web/JavaScript/New_in_JavaScript/1.6) (`map`, `filter`, `reduce`, `every` etc.) para manejar eventos asíncronos como si fuesen colecciones.

> Podemos considerar a RxJS como el [Lodash](https://lodash.com/) para eventos.

ReactiveX combina el [patrón Observador](https://es.wikipedia.org/wiki/Observer_\(patr%C3%B3n_de_dise%C3%B1o\)) con el [patrón Iterador](https://es.wikipedia.org/wiki/Iterador_\(patr%C3%B3n_de_dise%C3%B1o\)) y la [programación funcional con colecciones](https://martinfowler.com/articles/collection-pipeline/#NestedOperatorExpressions), constituyendo así la solución ideal para manejar secuencias de eventos.

Los conceptos esenciales de RxJS que resuelven el manejo asíncrono de eventos son los siguientes:

* Observable: representa la idea de una colección invocable de valores futuros o eventos.
* Observador: es una colleción de *callbacks* que sabe cómo escuchar a los valores proporcionados por el Observable.
* Suscripción: representa la ejecución de un Observable; es muy útil a la hora de cancelar la ejecución.
* Operadores: son funciones puras que permiten enfocar el manejo de las colecciones desde un estilo de programación funcional, con operaciones como `map`, `filter`, `concat`, `reduce` etc.
* Sujeto: es el equivalente a un EventEmitter, y la única manera de multidifundir un valor o un evento a múltiples Observadores.
* Planificadores: son despachadores centralizados para controlar la concurrencia, permitiendo coordinar cuándo ocurrirá la computación en `setTimeout`, `requestAnimationFrame` u otros.

## Primeros Ejemplos

Normalmente, tenemos que registrar *event listeners*.

```javascript
document.addEventListener("click", () => console.log("Clicked!"));
```

En lugar de hacerlo así, RxJS nos permite crear un Observable:

```javascript
import { fromEvent } from "rxjs";

fromEvent(document, "click").subscribe(() => console.log("Clicked!"));
```

## Pureza

Lo que hace que RxJS sea tan potente es su habilidad para producir valores mediante funciones puras. Esto equivale a un código menos propenso a errores.

Normalmente, se tendría que crear una función impura, planteando la posibilidad de que otros fragmentos del código puedan interferir con el estado.

```javascript
let count = 0;
document.addEventListener("click", () =>
  console.log(`Clicked ${++count} times`)
);
```

Usando RxJS, se puede aislar el estado.

```javascript
import { fromEvent } from "rxjs";
import { scan } from "rxjs/operators";

fromEvent(document, "click")
  .pipe(scan((count) => count + 1, 0))
  .subscribe((count) => console.log(`Clicked ${count} times`));
```

El operador `scan` funciona exactamente igual que el `reduce` para arrays. Recibe un valor que se le proporciona a una *callback*. El valor retornado por la *callback* se convierte en el siguiente valor que se proporcionará a la *callback*, la siguiente vez que esta sea ejecutada.

## Flow

RxJS tiene una gran cantidad de operadores que permiten controlar cómo fluyen los eventos a través de los Observables.

Así es como se permitiría únicamente un click por segundo, en JavaScript 'vainilla':

```javascript
let count = 0;
let rate = 1000;
let lastClick = Date.now() - rate;
document.addEventListener("click", () => {
  if (Date.now() - lastClick >= rate) {
    console.log(`Clicked ${++count} times`);
    lastClick = Date.now();
  }
});
```

Con RxJS:

```javascript
import { fromEvent } from "rxjs";
import { throttleTime, scan } from "rxjs/operators";

fromEvent(document, "click")
  .pipe(
    throttleTime(1000),
    scan((count) => count + 1, 0)
  )
  .subscribe((count) => console.log(`Clicked ${count} times`));
```

Otros operadores para el control del flujo son `filter`, `delay`, `debouncetime`, `take`, `takeUntil`, `distinct`, `distinctUntilChanged` etc.

## Valores

Los valores que pasan a través de un Observable se pueden transformar.

A continuación se muestra un ejemplo de cómo sumar la posición `x` del ratón por cada click, en JavaScript 'vainilla':

```javascript
let count = 0;
const rate = 1000;
let lastClick = Date.now() - rate;
document.addEventListener("click", (event) => {
  if (Date.now() - lastClick >= rate) {
    count += event.clientX;
    console.log(count);
    lastClick = Date.now();
  }
});
```

Con RxJS:

```javascript
import { fromEvent } from "rxjs";
import { throttleTime, map, scan } from "rxjs/operators";

fromEvent(document, "click")
  .pipe(
    throttleTime(1000),
    map((event) => event.clientX),
    scan((count, clientX) => count + clientX, 0)
  )
  .subscribe((count) => console.log(count));
```

Otros operadores que producen valores son `pluck`, `pairwise`, `sample` etc.


# Operadores


# Combinación

* [combineLatest](/operadores/combination/combinelatest)
* [concat](/operadores/combination/concat)
* [concatAll](/operadores/combination/concatall)
* [exhaust](/operadores/transformation/exhaust)
* [forkJoin](/operadores/combination/forkjoin)
* [merge](/operadores/combination/merge)
* [mergeAll](/operadores/combination/mergeall)
* [race](/operadores/combination/race)
* [startWith](/operadores/combination/startwith)
* [switchAll](/operadores/combination/switchall)
* [withLatestFrom](/operadores/combination/withlatestfrom)

## Operadores Obsoletos

* [combineAll](/operadores/combination/combineall) (obsoleto)
* [exhaust](/operadores/transformation/exhaust) (obsoleto)
* [zip](/operadores/combination/zip) (obsoleto)


# combineAll

Convierte un Observable de orden superior en uno de primer orden aplicando combineLatest cuando el Observable de orden superior se completa

<details>

<summary>Signatura</summary>

#### Firma

`combineAll<T, R>(project?: (...values: any[]) => R): OperatorFunction<T, R>`

#### Parámetros

#### Retorna

`OperatorFunction<T, R>`

</details>

## Descripción

![Diagrama de canicas del operador combineAll](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/combination/assets/images/marble-diagrams/join-creation/combineAll.png)

`combineAll` recibe un Observable de Observables y recoge todos los Observables que contenga. Una vez que el Observable externo se haya completado, se suscribe a todos los Observables recogidos y combina sus valores mediante la estrategia `combineLatest`, de manera que:

* Cada vez que un Observable interno emite, el Observable resultante emite.
* Cuando el Observable retornado emite, emite todos los valores recientes de manera que:
  * Si se proporciona una función `project`, se llama a dicha función con cada valor de cada Observable interno en el orden en el que llegaron, y el resultado de la función de proyección es lo que se emite en el Observable resultante.
  * Si no se proporciona una función `project`, el Observable resultante emite un array de todos los valores recientes.

## Ejemplos

**combineAll espera a recibir todos los valores, y los combina en un array**

[StackBlitz](https://stackblitz.com/edit/rxjs-combineall-1?file=index.ts)

```javascript
import { of } from "rxjs";
import { ajax } from "rxjs/ajax";
import { map, delay, combineAll } from "rxjs/operators";

const pokemonId$ = of(1, 5, 6);

function getPokemonName(id: number) {
  return ajax.getJSON(`https://pokeapi.co/api/v2/pokemon/${id}`).pipe(
    map(({ name }) => name),
    delay(2000)
  );
}

pokemonId$
  .pipe(
    map((id) => getPokemonName(id)),
    combineAll()
  )
  .subscribe(console.log);
// Salida: (2s) ['bulbasaur', 'charmeleon', 'charizard']
```

### Ejemplo de la documentación oficial

**Proyectar dos eventos click sobre un Observable intervalo, y aplicar combineAll**

```javascript
import { fromEvent, interval } from "rxjs";
import { map, combineAll, take } from "rxjs/operators";

const clicks = fromEvent(document, "click");
const higherOrder = clicks.pipe(
  map((ev) => interval(Math.random() * 2000).pipe(take(3))),
  take(2)
);
const result = higherOrder.pipe(combineAll());

result.subscribe((x) => console.log(x));
```

<details>

<summary>Sobrecargas</summary>

#### Firma

`combineAll(): OperatorFunction<ObservableInput<T>, T[]>`

#### Parámetros

No recibe ningún parámetro.

#### Retorna

`OperatorFunction<ObservableInput<T>, T[]>`

#### Firma

`combineAll(): OperatorFunction<any, T[]>`

#### Parámetros

No recibe ningún parámetro.

#### Retorna

`OperatorFunction<any, T[]>`

#### Firma

`combineAll(project: (...values: T[]) => R): OperatorFunction<ObservableInput<T>, R>`

#### Parámetros

#### Retorna

`OperatorFunction<ObservableInput<T>, R>`

#### Firma

`combineAll(project: (...values: any[]) => R): OperatorFunction<any, R>`

#### Parámetros

#### Retorna

`OperatorFunction<any, R>`

</details>

### Recursos adicionales

[![Source code](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/combination/assets/icons/source-code.png)](https://github.com/ReactiveX/rxjs/blob/master/src/internal/operators/combineAll.ts)

[Documentación oficial en inglés](https://rxjs.dev/api/operators/combineAll)


# combineLatest

Combina varios Observables para crear otro Observable cuyos valores se calculan a partir de las emisiones más recientes de cada uno de sus Observables de entrada

<details>

<summary>Signatura</summary>

#### Firma

`combineLatest<O extends ObservableInput<any>, R>(...observables: (SchedulerLike | O | ((...values: ObservedValueOf<O>[]) => R))[]): Observable<R>`

#### Parámetros

#### Retorna

`Observable<R>`: Un Observable de valores proyectados a partir de las emisiones más recientes de cada Observable de entrada, o un array de los de las emisiones más recientes de cada Observable de entrada.

</details>

## Descripción

Cuando uno de los Observables de entrada emite un valor, utiliza las últimas emisiones de todos los Observables de entrada para computar el valor que se emite en el Observable resultante.

![Diagrama de canicas del operador combineLatest](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/combination/assets/images/marble-diagrams/join-creation/combineLatest.png)

`combineLatest` combina los valores de todos los Observables de entrada. Para ello, se suscribe a cada uno de los Observables en orden, y cuando alguno de los Observables emite, recoge las emisiones más recientes de cada uno en un array. Por tanto, si se le proporcionan *n* Observables al operador, el Observable retornado siempre emitirá un array de *n* valores, en el orden en el que los Observables se hayan pasado como parámetros (el valor del primer Observable estará en la primera posición del array etc.)

La versión estática de `combineLatest` acepta un array de Observables o varios Observables pasados directamente como argumentos individuales. Se debe tener en cuenta que el array de Observables es una buena opción, si no se sabe de antemano cuántos Observables se van a combinar. Proporcionarle un array vacío a `combineLatest` resulta en un Observable que se completa inmediatamente.

Para asegurar que el array de salida siempre tenga la misma longitud, `combineLatest` espera a que todos los Observables de entrada emitan al menos una vez, antes de empezar a emitir. Esto quiere decir que si algún Observable emite varios valores antes de que los demás Observables emitan su primer valor, todos los valores que emita, excepto el último, se perderán. Por otra parte, si algún Observable se completa sin emitir ningún valor, el Observable resultante se completará en ese mismo momento sin emitir nada, ya que sería imposible incluir el valor del Observable completado en el array resultante. Además, si alguno de los Observables de entrada no emite ningún valor, ni llega a completarse nunca, `combineLatest` nunca emitirá ningún valor, ni llegará a completarse, dado que tiene que esperar a que todos los Observables emitan algún valor antes de poder emitir.

Si se le proporciona al menos un Observable a `combineLatest` y todos los Observables proporcionados han emitido un valor, el Observable resultante se completará cuando todos los Observables se completen. Por tanto, aunque alguno de los Observables de entrada se complete, `combineLatest` seguirá emitiendo valores mientras los demás Observables sigan haciéndolo. En el caso del Observable completado, su valor siempre será el último valor emitido. Por otra parte, si alguno de los Observables lanza un error, `combineLatest` también lanzará un error inmediatamente, y se cancelará la suscripción a todos los Observables restantes.

`combineLatest` acepta una función de proyección como parámetro opcional, que recibe como argumento todos los valores que se emitirían en el Observable resultante. La función `project` puede retornar cualquier tipo de valor, que será emitido en el Observable resultante en lugar del array por defecto. Se debe tener en cuenta que `project` no recibe como argumento una array de valores, sino los valores en sí mismos. Por tanto, la función `project`, por defecto, puede considerarse como una función que recoge en un array todos los argumentos que recibe.

## Ejemplos

### Ejemplos de la documentación oficial

Combinar dos Observables `timer`

```javascript
import { combineLatest, timer } from "rxjs";

const firstTimer = timer(0, 1000); // emit 0, 1, 2... after every second, starting from now
const secondTimer = timer(500, 1000); // emit 0, 1, 2... after every second, starting 0,5s from now
const combinedTimers = combineLatest(firstTimer, secondTimer);
combinedTimers.subscribe((value) => console.log(value));
// Salida:
// [0, 0] tras 0.5s
// [1, 0] tras 1s
// [1, 1] tras 1.5s
// [2, 1] tras 2s
```

Combinar un array de Observables

```javascript
import { combineLatest, of } from "rxjs";
import { delay, starWith } from "rxjs/operators";

const observables = [1, 5, 10].map((n) =>
  of(n).pipe(
    delay(n * 1000), // emite 0 y después emite n tras n seconds
    startWith(0)
  )
);
const combined = combineLatest(observables);
combined.subscribe((value) => console.log(value));
// Salida:
// [0, 0, 0] inmediatamente
// [1, 0, 0] tras 1s
// [1, 5, 0] tras 5s
// [1, 5, 10] tras 10s
```

Usar la función de proyección para calcular el índice de masa corporal dinámicamente

```javascript
import { combineLatest, of } from "rxjs";
import { map } from "rxjs/operators";

const weight = of(70, 72, 76, 79, 75);
const height = of(1.76, 1.77, 1.78);
const bmi = combineLatest(weight, height).pipe(map(([w, h]) => w / (h * h)));
bmi.subscribe((x) => console.log("BMI es " + x));

// Salida:
// BMI es 24.212293388429753
// BMI es 23.93948099205209
// BMI es 23.671253629592222
```

<details>

<summary>Sobrecargas</summary>

#### Firma

`combineLatest(sources: [O1], resultSelector: (v1: ObservedValueOf<O1>) => R, scheduler?: SchedulerLike): Observable<R>`

#### Parámetros

#### Retorna

`Observable<R>`

#### Firma

`combineLatest(sources: [O1, O2], resultSelector: (v1: ObservedValueOf<O1>, v2: ObservedValueOf<O2>) => R, scheduler?: SchedulerLike): Observable<R>`

#### Parámetros

#### Retorna

`Observable<R>`

#### Firma

`combineLatest(sources: [O1, O2, O3], resultSelector: (v1: ObservedValueOf<O1>, v2: ObservedValueOf<O2>, v3: ObservedValueOf<O3>) => R, scheduler?: SchedulerLike): Observable<R>`

#### Parámetros

#### Retorna

`Observable<R>`

#### Firma

`combineLatest(sources: [O1, O2, O3, O4], resultSelector: (v1: ObservedValueOf<O1>, v2: ObservedValueOf<O2>, v3: ObservedValueOf<O3>, v4: ObservedValueOf<O4>) => R, scheduler?: SchedulerLike): Observable<R>`

#### Parámetros

#### Retorna

`Observable<R>`

#### Firma

`combineLatest(sources: [O1, O2, O3, O4, O5], resultSelector: (v1: ObservedValueOf<O1>, v2: ObservedValueOf<O2>, v3: ObservedValueOf<O3>, v4: ObservedValueOf<O4>, v5: ObservedValueOf<O5>) => R, scheduler?: SchedulerLike): Observable<R>`

#### Parámetros

#### Retorna

`Observable<R>`

#### Firma

`combineLatest(sources: [O1, O2, O3, O4, O5, O6], resultSelector: (v1: ObservedValueOf<O1>, v2: ObservedValueOf<O2>, v3: ObservedValueOf<O3>, v4: ObservedValueOf<O4>, v5: ObservedValueOf<O5>, v6: ObservedValueOf<O6>) => R, scheduler?: SchedulerLike): Observable<R>`

#### Parámetros

#### Retorna

`Observable<R>`

#### Firma

`combineLatest(sources: O[], resultSelector: (...args: ObservedValueOf<O>[]) => R, scheduler?: SchedulerLike): Observable<R>`

#### Parámetros

#### Retorna

`Observable<R>`

#### Firma

`combineLatest(v1: O1, resultSelector: (v1: ObservedValueOf<O1>) => R, scheduler?: SchedulerLike): Observable<R>`

#### Parámetros

#### Retorna

`Observable<R>`

#### Firma

combineLatest(v1: O1, v2: O2, resultSelector: (v1: ObservedValueOf, v2: ObservedValueOf) => R, scheduler?: `SchedulerLike): Observable<R>`

#### Parámetros

#### Retorna

`Observable<R>`

#### Firma

`combineLatest(v1: O1, v2: O2, v3: O3, resultSelector: (v1: ObservedValueOf<O1>, v2: ObservedValueOf<O2>, v3: ObservedValueOf<O3>) => R, scheduler?: SchedulerLike): Observable<R>`

#### Parámetros

#### Retorna

`Observable<R>`

#### Firma

`combineLatest(v1: O1, v2: O2, v3: O3, v4: O4, resultSelector: (v1: ObservedValueOf<O1>, v2: ObservedValueOf<O2>, v3: ObservedValueOf<O3>, v4: ObservedValueOf<O4>) => R, scheduler?: SchedulerLike): Observable<R>`

#### Parámetros

#### Retorna

`Observable<R>`

#### Firma

`combineLatest(v1: O1, v2: O2, v3: O3, v4: O4, v5: O5, resultSelector: (v1: ObservedValueOf<O1>, v2: ObservedValueOf<O2>, v3: ObservedValueOf<O3>, v4: ObservedValueOf<O4>, v5: ObservedValueOf<O5>) => R, scheduler?: SchedulerLike): Observable<R>`

#### Parámetros

#### Retorna

`Observable<R>`

#### Firma

`combineLatest(v1: O1, v2: O2, v3: O3, v4: O4, v5: O5, v6: O6, resultSelector: (v1: ObservedValueOf<O1>, v2: ObservedValueOf<O2>, v3: ObservedValueOf<O3>, v4: ObservedValueOf<O4>, v5: ObservedValueOf<O5>, v6: ObservedValueOf<O6>) => R, scheduler?: SchedulerLike): Observable<R>`

#### Parámetros

#### Retorna

`Observable<R>`

#### Firma

`combineLatest(sources: [O1], scheduler: SchedulerLike): Observable<[ObservedValueOf<O1>]>`

#### Parámetros

#### Retorna

`Observable<[ObservedValueOf<O1>]>`

#### Firma

`combineLatest(sources: [O1, O2], scheduler: SchedulerLike): Observable<[ObservedValueOf<O1>, ObservedValueOf<O2>]>`

#### Parámetros

#### Retorna

`Observable<[ObservedValueOf<O1>, ObservedValueOf<O2>]>`

#### Firma

`combineLatest(sources: [O1, O2, O3], scheduler: SchedulerLike): Observable<[ObservedValueOf<O1>, ObservedValueOf<O2>, ObservedValueOf<O3>]>`

#### Parámetros

#### Retorna

`Observable<[ObservedValueOf<O1>, ObservedValueOf<O2>, ObservedValueOf<O3>]>`

#### Firma

`combineLatest(sources: [O1, O2, O3, O4], scheduler: SchedulerLike): Observable<[ObservedValueOf<O1>, ObservedValueOf<O2>, ObservedValueOf<O3>, ObservedValueOf<O4>]>`

#### Parámetros

#### Retorna

`Observable<[ObservedValueOf<O1>, ObservedValueOf<O2>, ObservedValueOf<O3>, ObservedValueOf<O4>]>`

#### Firma

`combineLatest(sources: [O1, O2, O3, O4, O5], scheduler: SchedulerLike): Observable<[ObservedValueOf<O1>, ObservedValueOf<O2>, ObservedValueOf<O3>, ObservedValueOf<O4>, ObservedValueOf<O5>]>`

#### Parámetros

#### Retorna

`Observable<[ObservedValueOf<O1>, ObservedValueOf<O2>, ObservedValueOf<O3>, ObservedValueOf<O4>, ObservedValueOf<O5>]>`

#### Firma

`combineLatest(sources: [O1, O2, O3, O4, O5, O6], scheduler: SchedulerLike): Observable<[ObservedValueOf<O1>, ObservedValueOf<O2>, ObservedValueOf<O3>, ObservedValueOf<O4>, ObservedValueOf<O5>, ObservedValueOf<O6>]>`

#### Parámetros

#### Retorna

`Observable<[ObservedValueOf<O1>, ObservedValueOf<O2>, ObservedValueOf<O3>, ObservedValueOf<O4>, ObservedValueOf<O5>, ObservedValueOf<O6>]>`

#### Firma

`combineLatest(sources: O[], scheduler: SchedulerLike): Observable<ObservedValueOf<O>[]>`

#### Parámetros

#### Retorna

`Observable<ObservedValueOf<O>[]>`

#### Firma

`combineLatest(sources: [O1]): Observable<[ObservedValueOf<O1>]>`

#### Parámetros

#### Retorna

`combineLatest(sources: [O1, O2]): Observable<[ObservedValueOf<O1>, ObservedValueOf<O2>]>`

#### Firma

#### Parámetros

#### Retorna

`combineLatest(sources: [O1, O2, O3]): Observable<[ObservedValueOf<O1>, ObservedValueOf<O2>, ObservedValueOf<O3>]>`

#### Firma

#### Parámetros

#### Retorna

`combineLatest(sources: [O1, O2, O3, O4]): Observable<[ObservedValueOf<O1>, ObservedValueOf<O2>, ObservedValueOf<O3>, ObservedValueOf<O4>]>`

#### Firma

#### Parámetros

#### Retorna

\`combineLatest(sources: \[O1, O2, O3, O4, O5]): Observable<\[ObservedValueOf, ObservedValueOf, ObservedValueOf, ObservedValueOf,

#### FirmaObservedValueOf]>\`

#### Parámetros

#### Retorna

\`combineLatest(sources: \[O1, O2, O3, O4, O5, O6]): Observable<\[ObservedValueOf, ObservedValueOf, ObservedValueOf, ObservedValueOf,

#### FirmaObservedValueOf, ObservedValueOf]>\`

#### Parámetros

#### Retorna

`combineLatest(sources: O[]): Observable<ObservedValueOf<O>[]>`

#### Firma

#### Parámetros

#### Retorna

`combineLatest(v1: O1, scheduler?: SchedulerLike): Observable<[ObservedValueOf<O1>]>`

#### Firma

#### Parámetros

#### Retorna

`Observable<[ObservedValueOf<O1>]>`

#### Firma

`combineLatest(v1: O1, v2: O2, scheduler?: SchedulerLike): Observable<[ObservedValueOf<O1>, ObservedValueOf<O2>]>`

#### Parámetros

#### Retorna

`Observable<[ObservedValueOf<O1>, ObservedValueOf<O2>]>`

#### Firma

`combineLatest(v1: O1, v2: O2, v3: O3, scheduler?: SchedulerLike): Observable<[ObservedValueOf<O1>, ObservedValueOf<O2>, ObservedValueOf<O3>]>`

#### Parámetros

#### Retorna

`Observable<[ObservedValueOf<O1>, ObservedValueOf<O2>, ObservedValueOf<O3>]>`

#### Firma

`combineLatest(v1: O1, v2: O2, v3: O3, v4: O4, scheduler?: SchedulerLike): Observable<[ObservedValueOf<O1>, ObservedValueOf<O2>, ObservedValueOf<O3>, ObservedValueOf<O4>]>`

#### Parámetros

#### Retorna

`Observable<[ObservedValueOf<O1>, ObservedValueOf<O2>, ObservedValueOf<O3>, ObservedValueOf<O4>]>`

#### Firma

`combineLatest(v1: O1, v2: O2, v3: O3, v4: O4, v5: O5, scheduler?: SchedulerLike): Observable<[ObservedValueOf<O1>, ObservedValueOf<O2>, ObservedValueOf<O3>, ObservedValueOf<O4>, ObservedValueOf<O5>]>`

#### Parámetros

#### Retorna

`Observable<[ObservedValueOf<O1>, ObservedValueOf<O2>, ObservedValueOf<O3>, ObservedValueOf<O4>, ObservedValueOf<O5>]>`

#### Firma

`combineLatest(v1: O1, v2: O2, v3: O3, v4: O4, v5: O5, v6: O6, scheduler?: SchedulerLike): Observable<[ObservedValueOf<O1>, ObservedValueOf<O2>, ObservedValueOf<O3>, ObservedValueOf<O4>, ObservedValueOf<O5>, ObservedValueOf<O6>]>`

#### Parámetros

#### Retorna

`Observable<[ObservedValueOf<O1>, ObservedValueOf<O2>, ObservedValueOf<O3>, ObservedValueOf<O4>, ObservedValueOf<O5>, ObservedValueOf<O6>]>`

#### Firma

`combineLatest(...observables: O[]): Observable<any[]>`

#### Parámetros

#### Retorna

`Observable<any[]>`

#### Firma

`combineLatest(...observables: any[]): Observable<R>`

#### Parámetros

#### Retorna

`Observable<R>`

#### Firma

`combineLatest(array: O[], resultSelector: (...values: ObservedValueOf<O>[]) => R, scheduler?: SchedulerLike): Observable<R>`

#### Parámetros

Tipo: `(...values: ObservedValueOf[]) => R`.

#### Retorna

`Observable<R>`

#### Firma

`combineLatest(...observables: (SchedulerLike | O)[]): Observable<any[]>`

#### Parámetros

#### Retorna

`Observable<any[]>`

#### Firma

`combineLatest(...observables: (SchedulerLike | O | ((...values: ObservedValueOf<O>[]) => R))[]): Observable<R>`

#### Parámetros

#### Retorna

`Observable<R>`

#### Firma

`combineLatest(...observables: any[]): Observable<R>`

#### Parámetros

#### Retorna

`Observable<R>`

</details>

### Recursos adicionales

[![Source code](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/combination/assets/icons/source-code.png)](https://github.com/ReactiveX/rxjs/blob/master/src/internal/operators/combineLatest.ts)

[Documentación oficial en inglés](https://rxjs.dev/api/index/function/combineLatest)


# concat

Concatena varios Observables de entrada, uno tras otro, emitiendo secuencialmente todos los valores de cada uno de ellos

💡 Para emitir valores de varios Observables a la vez (concurrentemente), se puede utilizar [merge](https://github.com/puntotech/rxjs-docu/blob/master/operators/combination/merge/README.md)

### Firma

`concat<O extends ObservableInput<any>, R>(...observables: (SchedulerLike | O)[]): Observable<ObservedValueOf<O> | R>`

### Parámetros

| observables | Tipo: `(SchedulerLike \| O)[]`. |
| ----------- | ------------------------------- |

### Retorna

`Observable<ObservedValueOf<O> | R>`: Todos los valores de cada Observable de entrada fusionados en un solo Observable, por orden.

## Descripción

Concatena varios Observables, uno tras otro, emitiendo secuencialmente sus valores.

![Diagrama de canicas del operador concat](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/combination/assets/images/marble-diagrams/join-creation/concat.png)

`concat` une varios Observables, suscribiéndose a ellos de uno en uno y fusionando los valores que emitan en el Observable resultante. Los Observables de entrada se pueden proporcionar en un array, o directamente como argumentos. Proporcionarle un array vacío a `concat` resulta en un Observable que se completa inmediatamente.

`concat` se suscribe al primer Observable de entrada y emite todos sus valores intactos, sin cambiarlos ni transformarlos. Cuando ese primer Observable se completa, se suscribe al siguiente Observable y, de nuevo, emite todos sus valores. Este proceso se repite hasta que el operador agote todos los Observables de entrada. Cuando el último Observable de entrada se complete, `concat` también se completará. `concat` emite los valores de un solo Observable cada vez.

`concat` es el equivalente a utilizar el operador `merge` con el parámetro de concurrencia `1`.

Si alguno de los Observables de entrada nunca llega a completarse, `concat` tampoco se completará y los demás Observables de entrada nunca llegarán a ser suscritos. Por otra parte, si alguno de los Observables de entrada se completa inmediatamente después de ser suscrito, será invisible para `concat`, que se suscribirá al siguiente Observable.

Si alguno de los Observables de entrada lanza un error, en lugar de suscribirse al siguiente Observable, `concat` también lanzará un error inmediatamente, y no llegará a suscribirse a los Observables de entrada siguientes al que haya lanzado el error.

Si se le pasa el mismo Observable a `concat` varias veces, su flujo de emisiones se repetirá en cada suscripción. Se puede repetir un Observable tantas veces como se quiera. Sin embargo, si pasarle el mismo Observable a `concat` 1000 veces resulta demasiado tedioso, siempre se puede utilizar [repeat](https://github.com/puntotech/rxjs-docu/blob/master/operators/utility/repeat/README.md).

## Ejemplos

**Concatenar varios Observables distintos**

[StackBlitz](https://stackblitz.com/edit/docu-rxjs-concat?file=index.ts)

```javascript
import { range, from, concat } from "rxjs";
import { ajax } from "rxjs/ajax";

const number$ = range(1, 4);

const fruit$ = from(["Fresa", "Cereza", "Arándano"]);

const totoroFilmData$ = ajax.getJSON(
  "https://ghibliapi.herokuapp.com/films/58611129-2dbc-4a81-a72f-77ddfc1b1b49"
);

concat(number$, fruit$, totoroFilmData$).subscribe(console.log);
// Salida: 1, 2, 3, 4, 'Fresa', 'Cereza', 'Arándano', { ..., title: 'My Neighbor Totoro', description: 'Two sisters move to the country...', ...}
```

**Concatenar el mismo Observable para repetirlo**

[StackBlitz](https://stackblitz.com/edit/docu-rxjs-concat-2?file=index.ts)

```javascript
import { from, concat } from "rxjs";

const message$ = from(["RxJS mola"]);

concat(message$, message$, message$).subscribe(console.log);
// Salida: 'RxJS mola', 'RxJS mola', 'RxJS mola'
```

**Si uno de los Observables de entrada nunca llega a completarse, concat nunca se suscribirá a los siguientes Observables de entrada**

[StackBlitz](https://stackblitz.com/edit/docu-rxjs-concat-3?file=index.ts)

```javascript
import { interval, from, concat } from "rxjs";

const infinite$ = interval(1000);
const message$ = from(["Nunca", "se", "emitirá"]);

concat(infinite$, message$).subscribe(console.log);
// Salida: 0, 1, 2, 3...
```

**Si alguno de los Observables de entrada lanza un error, el Observable resultante lanzará un error inmediatamente, y el flujo se terminará**

[StackBlitz](https://stackblitz.com/edit/docu-rxjs-concat-4?file=index.ts)

```javascript
import { throwError, from, concat } from "rxjs";

const message$ = from(["Este mensaje se emitirá"]);
const error$ = throwError("Oh no");
const sadMessage$ = from(["No se llega a emitir :("]);

concat(message$, error$, sadMessage$).subscribe(console.log, console.error);
// Salida: 'Este mensaje se emitirá', (error) Oh no
```

### Ejemplos de la documentación oficial

**Concatenar un temporizador que cuente del 0 al 3 con una secuencia síncrona de los números del 1 al 10**

```javascript
import { concat, interval, range } from "rxjs";
import { take } from "rxjs/operators";

const timer = interval(1000).pipe(take(4));
const sequence = range(1, 10);
const result = concat(timer, sequence);
result.subscribe((x) => console.log(x));

// Salida:
// 0 -1000ms-> 1 -1000ms-> 2 -1000ms-> 3 -inmediatamente-> 1 ... 10
```

**Concatenar 3 Observables**

```javascript
import { concat, interval } from "rxjs";
import { take } from "rxjs/operators";

const timer1 = interval(1000).pipe(take(10));
const timer2 = interval(2000).pipe(take(6));
const timer3 = interval(500).pipe(take(10));

const result = concat(timer1, timer2, timer3);
result.subscribe((x) => console.log(x));

// Salida:
// (Los valores se imprimen por consola secuencialmente)
// -1000ms-> 0 -1000ms-> 1 -1000ms-> ... 9
// -2000ms-> 0 -2000ms-> 1 -2000ms-> ... 5
// -500ms-> 0 -500ms-> 1 -500ms-> ... 9
```

**Concatenar el mismo Observable para repetirlo**

```javascript
import { concat, interval } from "rxjs";
import { take } from "rxjs/operators";

const timer = interval(1000).pipe(take(2));

concat(timer, timer) // ¡Concatenando el mismo Observable!
  .subscribe(
    (value) => console.log(value),
    (err) => {},
    () => console.log("...y se acabó!")
  );

// Salida:
// 0 tras 1s
// 1 tras 2s
// 0 tras 3s
// 1 tras 4s
// "...y se acabó!" tras 4s
```

<details>

<summary>Sobrecargas</summary>

#### Firma

`concat(v1: O1, scheduler: SchedulerLike): Observable<ObservedValueOf<O1>>`

#### Parámetros

#### Retorna

`Observable<ObservedValueOf<O1>>`

#### Firma

`concat(v1: O1, v2: O2, scheduler: SchedulerLike): Observable<ObservedValueOf<O1> | ObservedValueOf<O2>>`

#### Parámetros

#### Retorna

`Observable<ObservedValueOf<O1> | ObservedValueOf<O2>>`

#### Firma

`concat(v1: O1, v2: O2, v3: O3, scheduler: SchedulerLike): Observable<ObservedValueOf<O1> | ObservedValueOf<O2> | ObservedValueOf<O3>>`

#### Parámetros

#### Retorna

`Observable<ObservedValueOf<O1> | ObservedValueOf<O2> | ObservedValueOf<O3>>`

#### Firma

`concat(v1: O1, v2: O2, v3: O3, v4: O4, scheduler: SchedulerLike): Observable<ObservedValueOf<O1> | ObservedValueOf<O2> | ObservedValueOf<O3> | ObservedValueOf<O4>>`

#### Parámetros

#### Retorna

`Observable<ObservedValueOf<O1> | ObservedValueOf<O2> | ObservedValueOf<O3> | ObservedValueOf<O4>>`

#### Firma

`concat(v1: O1, v2: O2, v3: O3, v4: O4, v5: O5, scheduler: SchedulerLike): Observable<ObservedValueOf<O1> | ObservedValueOf<O2> | ObservedValueOf<O3> | ObservedValueOf<O4> | ObservedValueOf<O5>>`

#### Parámetros

#### Retorna

`Observable<ObservedValueOf<O1> | ObservedValueOf<O2> | ObservedValueOf<O3> | ObservedValueOf<O4> | ObservedValueOf<O5>>`

#### Firma

`concat(v1: O1, v2: O2, v3: O3, v4: O4, v5: O5, v6: O6, scheduler: SchedulerLike): Observable<ObservedValueOf<O1> | ObservedValueOf<O2> | ObservedValueOf<O3> | ObservedValueOf<O4> | ObservedValueOf<O5> | ObservedValueOf<O6>>`

#### Parámetros

#### Retorna

`Observable<ObservedValueOf<O1> | ObservedValueOf<O2> | ObservedValueOf<O3> | ObservedValueOf<O4> | ObservedValueOf<O5> | ObservedValueOf<O6>>`

#### Firma

`concat(v1: O1): Observable<ObservedValueOf<O1>>`

#### Parámetros

#### Retorna

`Observable<ObservedValueOf<O1>>`

#### Firma

`concat(v1: O1, v2: O2): Observable<ObservedValueOf<O1> | ObservedValueOf<O2>>`

#### Parámetros

#### Retorna

`Observable<ObservedValueOf<O1> | ObservedValueOf<O2>>`

#### Firma

`concat(v1: O1, v2: O2, v3: O3): Observable<ObservedValueOf<O1> | ObservedValueOf<O2> | ObservedValueOf<O3>>`

#### Parámetros

#### Retorna

`Observable<ObservedValueOf<O1> | ObservedValueOf<O2> | ObservedValueOf<O3>>`

#### Firma

`concat(v1: O1, v2: O2, v3: O3, v4: O4): Observable<ObservedValueOf<O1> | ObservedValueOf<O2> | ObservedValueOf<O3> | ObservedValueOf<O4>>`

#### Parámetros

#### Retorna

`Observable<ObservedValueOf<O1> | ObservedValueOf<O2> | ObservedValueOf<O3> | ObservedValueOf<O4>>`

#### Firma

`concat(v1: O1, v2: O2, v3: O3, v4: O4, v5: O5): Observable<ObservedValueOf<O1> | ObservedValueOf<O2> | ObservedValueOf<O3> | ObservedValueOf<O4> | ObservedValueOf<O5>>`

#### Parámetros

#### Retorna

`Observable<ObservedValueOf<O1> | ObservedValueOf<O2> | ObservedValueOf<O3> | ObservedValueOf<O4> | ObservedValueOf<O5>>`

#### Firma

`concat(v1: O1, v2: O2, v3: O3, v4: O4, v5: O5, v6: O6): Observable<ObservedValueOf<O1> | ObservedValueOf<O2> | ObservedValueOf<O3> | ObservedValueOf<O4> | ObservedValueOf<O5> | ObservedValueOf<O6>>`

#### Parámetros

#### Retorna

`Observable<ObservedValueOf<O1> | ObservedValueOf<O2> | ObservedValueOf<O3> | ObservedValueOf<O4> | ObservedValueOf<O5> | ObservedValueOf<O6>>`

#### Firma

`concat(...observables: O[]): Observable<ObservedValueOf<O>>`

#### Parámetros

#### Retorna

`Observable<ObservedValueOf<O>>`

#### Firma

`concat(...observables: (SchedulerLike | O)[]): Observable<ObservedValueOf<O>>`

#### Parámetros

#### Retorna

`Observable<ObservedValueOf<O>>`

#### Firma

`concat(...observables: any[]): Observable<R>`

#### Parámetros

#### Retorna

`Observable<R>`

#### Firma

`concat(...observables: any[]): Observable<R>`

#### Parámetros

#### Retorna

`Observable<R>`

</details>

### Recursos adicionales

[![Source code](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/combination/assets/icons/source-code.png)](https://github.com/ReactiveX/rxjs/blob/master/src/internal/observable/concat.ts)

[Documentación oficial en inglés](https://rxjs.dev/api/index/function/concat)


# concatAll

Convierte un Observable de orden superior en uno de primer orden concatenando los Observables internos en orden

<details>

<summary>Signatura</summary>

#### Firma

`concatAll<T>(): OperatorFunction<ObservableInput<T>, T>`

#### Parámetros

No recibe ningún parámetro.

#### Retorna

`OperatorFunction<ObservableInput<T>, T>`: Un Observable que emite los valores emitidos por los Observables internos concatenados.

</details>

## Descripción

Convierte un Observable de orden superior en uno de primer orden concatenando los Observables internos uno detrás de otro.

![Diagrama de canicas del operador concatAll](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/combination/assets/images/marble-diagrams/join-creation/concatAll.png)

Concatena cada Observable emitido por la fuente (un Observable de orden superior), de forma secuencial. Se suscribe a cada Observable interno si, y solo si, el Observable interno anterior se ha completado, y emite todos sus valores en el Observable resultante.

Advertencia: Si el Observable fuente emite Observables de forma rápida e indefinida, y los Observables internos que emite se completan más lento de lo que la fuente emite valores, se pueden dar problemas de memoria al almacenarse los Observables internos en un búfer infinito.

💡 `concatAll` es equivalente a `mergeAll` con un parámetro de concurrencia de valor 1.

## Ejemplos

**concatAll se suscribe a cada Observable interno si, y solo si, el Observable interno anterior se ha completado. Esto implica que espera a que cada petición esté terminada antes de hacer una nueva**

[StackBlitz](https://stackblitz.com/edit/rxjs-concatall-1?file=index.ts)

```javascript
import { concatAll, map, delay } from "rxjs/operators";
import { ajax } from "rxjs/ajax";
import { of } from "rxjs";

const pokemonId$ = of(1, 5, 6);

function getPokemonName(id: number) {
  return ajax.getJSON(`https://pokeapi.co/api/v2/pokemon/${id}`).pipe(
    map(({ name }) => name),
    delay(2000)
  );
}

pokemonId$
  .pipe(
    map((id) => getPokemonName(id)),
    concatAll()
  )
  .subscribe(console.log);
// Salida: (2s) bulbasaur, (2s) charmeleon, (2s) charizard
```

### Ejemplo de la documentación oficial

**Por cada evento click, emitir los números del 0 al 3 a intervalos de 1s, sin concurrencia**

```javascript
import { fromEvent, interval } from "rxjs";
import { map, take, concatAll } from "rxjs/operators";

const clicks = fromEvent(document, "click");
const higherOrder = clicks.pipe(map((ev) => interval(1000).pipe(take(4))));
const firstOrder = higherOrder.pipe(concatAll());
firstOrder.subscribe((x) => console.log(x));

// Salida:
// (Los resultados no son concurrentes)
// Por cada click en el "document" se emitirán los números del 0 al 3 a intervalos de 1s
// Un click = 1000ms-> 0 -1000ms-> 1 -1000ms-> 2 -1000ms-> 3
```

### Recursos adicionales

[![Source code](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/combination/assets/icons/source-code.png)](https://github.com/ReactiveX/rxjs/blob/master/src/internal/operators/concatAll.ts)

[Documentación oficial en inglés](https://rxjs.dev/api/operators/concatAll)


# exhaust

Convierte un Observable de orden superior en uno de primer orden ignorando los Observables internos mientras el Observable interno actual no se haya completado

<details>

<summary>Signatura</summary>

#### Firma

`exhaust<T>(): OperatorFunction<any, T>`

#### Parámetros

No recibe ningún parámetro.

#### Retorna

`OperatorFunction<any, T>`: Un Observable que recibe un Observable de orden superior y propaga el primer Observable hasta que se completa, antes de suscribirse al siguiente Observable.

</details>

## Descripción

Convierte un Observable de orden superior en uno de primer orden ignorando los Observables internos mientras el Observable interno actual no se haya completado.

![Diagrama de canicas del operador exhaust](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/combination/assets/images/marble-diagrams/join-creation/exhaust.png)

`exhaust` se suscribe a un Observable que emite Observables, también conocido como Observable de orden superior. Cuando recibe un Observable interno, el Observable resultante comienza a emitir sus emisiones. Hasta este punto, se comporta igual que `mergeAll`. Sin embargo, `exhaust` ignora cada Observable interno nuevo hasta que el Observable actual no se haya completado. Una vez esté completo, aceptará el siguiente Observable interno y comenzará a emitir sus valores, repitiendo el proceso.

## Ejemplos

**Ignorar todos los Observables internos hasta que el Observable interno actual esté completo**

[StackBlitz](https://stackblitz.com/edit/docu-rxjs-exhaust?file=index.ts)

```javascript
import { exhaust, map, delay } from "rxjs/operators";
import { ajax } from "rxjs/ajax";
import { of } from "rxjs";

const pokemonId$ = of(1, 5, 6);

function getPokemonName(id: number) {
  return ajax.getJSON(`https://pokeapi.co/api/v2/pokemon/${id}`).pipe(
    map(({ name }) => name),
    delay(2000)
  );
}

pokemonId$
  .pipe(
    map((id) => getPokemonName(id)),
    exhaust()
  )
  .subscribe(console.log);
// Salida: bulbasaur
```

### Ejemplo de la documentación oficial

**Por cada click, ejecutar un temporizador, únicamente si no hay ningún temporizador activo**

```javascript
import { fromEvent, interval } from "rxjs";
import { exhaust, map, take } from "rxjs/operators";

const clicks = fromEvent(document, "click");
const higherOrder = clicks.pipe(map((ev) => interval(1000).pipe(take(5))));
const result = higherOrder.pipe(exhaust());
result.subscribe((x) => console.log(x));
```

### Recursos adicionales

[![Source code](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/combination/assets/icons/source-code.png)](https://github.com/ReactiveX/rxjs/blob/master/src/internal/operators/exhaust.ts)

[Documentación oficial en inglés](https://rxjs.dev/api/operators/exhaust)


# forkJoin

Acepta un Array de Observables o un diccionario de Observables, y retorna otro Observable que emite o bien un array de valores en el mismo orden que el array proporcionado, o un diccionario de valores

<details>

<summary>Signatura</summary>

#### Firma

`forkJoin(...sources: any[]): Observable<any>`

#### Parámetros

#### Retorna

`Observable<any>`: Un Observable que emite o un array de las últimas emisiones de los Observables de entrada o el valor de la función de proyección.

</details>

## Descripción

Espera a que todos los Observables se completen, y combina sus últimas emisiones.

![Diagrama de canicas del operador forkJoin](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/combination/assets/images/marble-diagrams/join-creation/forkJoin.png)

`forkJoin` es un operador que recibe un array de Observables o un diccionario de Observables como parámetro de entrada. Si no se proporciona ningún Observable de entrada, el Observable resultante se completa inmediatamente.

`forkJoin` espera a que todos los Observables de entrada se completen, y entonces emite un array u objeto con la última emisión de cada uno de estos Observables.

Si se le proporciona un array de *n* Observables a `forkJoin`, el array resultante contendrá *n* valores, donde el primer valor es la última emisión del primer Observable, el segundo valor es la última emisión del segundo Observable, y así sucesivamente.

Si se le proporciona un diccionario de Observables a `forkJoin` el objeto resultante tendrá las mismas claves que el diccionario. Los últimos valores que se hayan emitido por cada Observable de entrada estarán situados bajo la clave correspondiente.

`forkJoin` emite una única vez, y se completará justo después. Si se necesita emitir valores combinados durante el ciclo de vida de los Observables de entrada, se recomienza utilizar [combineLatest](https://github.com/puntotech/rxjs-docu/blob/master/operators/combination/combineLatest/README.md) o [zip](https://github.com/puntotech/rxjs-docu/blob/master/operators/combination/zip/README.md).

Para que el array resultante tenga la misma longitud que el número de Observables de entrada, cuando alguno de dichos Observables se complete sin emitir ningún valor, `forkJoin` también se completará y no emitirá ningún valor, aunque ya tenga recogidos algunos valores de los demás Observables. Además, si hay algún Observable que nunca llegue a completarse, `forkJoin` tampoco se completará, a no ser que, en cualquier momento, alguno de los demás Observables de entrada se complete sin emitir ningún valor, lo que nos trae de vuelta al caso anterior. Como norma general, para que `forkJoin` pueda emitir un valor, todos los Observables de entrada tienen que emitir como mínimo un valor, y completarse.

Si alguno de los Observables de entrada lanza un error, `forkJoin` también lo hará, y se cancelará la suscripción a todos los demás Observables de entrada.

Opcionalmente, `forkJoin` recibe una función de proyección, que se llamará con los valores que normalmente se emitirían en el array resultante. El resultado de la función de proyección, sea cual sea, se emitirá en el Observable resultante. Debido a esto, se puede considerar a la función de proyección como una función que recoge todos los argumentos que recibe en un array. La función de proyección se llamará solo cuando el Observable resultante tenga que emitir un valor.

## Ejemplos

**Combinar la última emisión de dos Observables distintos**

[StackBlitz](https://stackblitz.com/edit/docu-rxjs-forkjoin?file=index.ts)

```javascript
import { forkJoin, from, of } from "rxjs";

const language$ = forkJoin([
  of("Java", "Ruby", "Haskell"),
  from(["Orientado a objetos", "Multiparadigma", "Funcional"]),
]);

// Combinar la última emisión de dos Observables distintos
language$.subscribe(console.log);
// Salida: ["Haskell", "Funcional"]
```

**Combinar la última emisión de dos Observables distintos, contenidos en un diccionario de datos**

[StackBlitz](https://stackblitz.com/edit/docu-rxjs-forkjoin-2?file=index.ts)

```javascript
import { forkJoin, from, of } from "rxjs";

const languageDictionary$ = forkJoin({
  language: of("Java", "Ruby", "Haskell"),
  type: from(["Orientado a objetos", "Multiparadigma", "Funcional"]),
});

languageDictionary$.subscribe(console.log);
// Salida: { language: Haskell, type: Funcional }
```

**Si alguno de los Observables de entrada lanza un error, el Observable resultante lanzará un error inmediatamente, y el flujo se terminará**

[StackBlitz](https://stackblitz.com/edit/docu-rxjs-forkjoin-3?file=index.ts)

```javascript
import { throwError, from, forkJoin } from "rxjs";

const message$ = from(["Este mensaje se emitirá"]);
const error$ = throwError("Oh no");
const sadMessage$ = from(["No se llega a emitir :("]);

forkJoin([message$, error$, sadMessage$]).subscribe(console.log, console.error);
// Salida: 'Este mensaje se emitirá', (error) Oh no
```

**Si se utiliza el operador `catchError` en el Observable de entrada que lanza el error, el Observable resultante se completará sin problemas**

[StackBlitz](https://stackblitz.com/edit/docu-rxjs-forkjoin-4?file=index.ts)

```javascript
import { from, forkJoin, of, throwError } from "rxjs";
import { catchError } from "rxjs/operators";

const message$ = from(["Este mensaje se emitirá"]);

// Capturando el error con catchError
const error$ = throwError("Oh no").pipe(catchError((err) => of(err)));

const happyMessage$ = from(["Ahora sí se emite :)"]);

forkJoin([message$, error$, happyMessage$]).subscribe(console.log);
// Salida: ['Este mensaje se emitirá', 'Oh no', 'Ahora sí se emite :)']
```

### Ejemplos de la documentación oficial

**Usar forkJoin con un diccionario de Observables de entrada**

```javascript
import { forkJoin, of, timer } from "rxjs";

const observable = forkJoin({
  foo: of(1, 2, 3, 4),
  bar: Promise.resolve(8),
  baz: timer(4000),
});
observable.subscribe({
  next: (value) => console.log(value),
  complete: () => console.log("¡Y así es como acaba!"),
});

// Salida:
// { foo: 4, bar: 8, baz: 0 } tras 4 segundos
// "¡Y así es como acaba!" inmediatamente después
```

**Usar forkJoin con un array de Observables de entrada**

```javascript
import { forkJoin, of } from "rxjs";

const observable = forkJoin([of(1, 2, 3, 4), Promise.resolve(8), timer(4000)]);
observable.subscribe({
  next: (value) => console.log(value),
  complete: () => console.log("¡Y así es como acaba!"),
});

// Salida:
// [4, 8, 0] tras 4 segundos
// "¡Y así es como acaba!" inmediatamente después
```

<details>

<summary>Sobrecargas</summary>

#### Firma

`forkJoin(v1: SubscribableOrPromise<T>): Observable<[T]>`

#### Parámetros

#### Retorna

`Observable<[T]>`

#### Firma

`forkJoin(v1: any, v2: any): Observable<[T, T2]>`

#### Parámetros

#### Retorna

`Observable<[T, T2]>`

#### Firma

`forkJoin(v1: any, v2: any, v3: any): Observable<[T, T2, T3]>`

#### Parámetros

#### Retorna

`Observable<[T, T2, T3]>`

#### Firma

`forkJoin(v1: any, v2: any, v3: any, v4: any): Observable<[T, T2, T3, T4]>`

#### Parámetros

#### Retorna

`Observable<[T, T2, T3, T4]>`

#### Firma

`forkJoin(v1: any, v2: any, v3: any, v4: any, v5: any): Observable<[T, T2, T3, T4, T5]>`

#### Parámetros

#### Retorna

`Observable<[T, T2, T3, T4, T5]>`

#### Firma

`forkJoin(v1: any, v2: any, v3: any, v4: any, v5: any, v6: any): Observable<[T, T2, T3, T4, T5, T6]>`

#### Parámetros

#### Retorna

`Observable<[T, T2, T3, T4, T5, T6]>`

#### Firma

`forkJoin(sources: [any]): Observable<[A]>`

#### Parámetros

#### Retorna

`Observable<[A]>`

#### Firma

`forkJoin(sources: [any, any]): Observable<[A, B]>`

#### Parámetros

#### Retorna

`Observable<[A, B]>`

#### Firma

`forkJoin(sources: [any, any, any]): Observable<[A, B, C]>`

#### Parámetros

#### Retorna

`Observable<[A, B, C]>`

#### Firma

`forkJoin(sources: [any, any, any, any]): Observable<[A, B, C, D]>`

#### Parámetros

#### Retorna

`Observable<[A, B, C, D]>`

#### Firma

`forkJoin(sources: [any, any, any, any, any]): Observable<[A, B, C, D, E]>`

#### Parámetros

#### Retorna

`Observable<[A, B, C, D, E]>`

#### Firma

`forkJoin(sources: [any, any, any, any, any, any]): Observable<[A, B, C, D, E, F]>`

#### Parámetros

#### Retorna

`Observable<[A, B, C, D, E, F]>`

#### Firma

`forkJoin(sources: A): Observable<ObservedValuesFromArray<A>[]>`

#### Parámetros

#### Retorna

`Observable<ObservedValuesFromArray<A>[]>`

#### Firma

`forkJoin(sourcesObject: {}): Observable<never>`

#### Parámetros

#### Retorna

`Observable<never>`

#### Firma

`forkJoin(sourcesObject: T): Observable<{[K in keyof T]: ObservedValueOf<T[K]>;}>`

#### Parámetros

#### Retorna

`Observable<{ [K in keyof T]: ObservedValueOf<T[K]>; }>`

#### Firma

`forkJoin(...args: any[]): Observable<any>`

#### Parámetros

#### Retorna

`Observable<any>`

#### Firma

`forkJoin(...sources: any[]): Observable<T[]>`

#### Parámetros

#### Retorna

`Observable<T[]>`

</details>

### Recursos adicionales

[![Source code](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/combination/assets/icons/source-code.png)](https://github.com/ReactiveX/rxjs/blob/master/src/internal/observable/forkJoin.ts)

[Documentación oficial en inglés](https://rxjs.dev/api/index/function/forkJoin)


# merge

Crea un Observable de salida que emite concurrentemente los valores de todos los Observables de entrada

## Descripción

Une varios Observables en uno solo.

![Diagrama de canicas del operador merge](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/combination/assets/images/marble-diagrams/join-creation/merge.png)

`merge` se subscribe a cada Observable de entrada de forma concurrente, y emite sus valores, sin transformarlos, en el Observable resultante. El Observable resultante solo se completa cuando todos los Observables de entrada se hayan completado.

Cualquier error lanzado por un Observable de entrada será emitido inmediatamente en el Observable resultante.

## Ejemplos

**Unir dos Observables ajax**

[StackBlitz](https://stackblitz.com/edit/docu-rxjs-merge?file=index.ts)

```javascript
import { concat } from "rxjs";
import { ajax } from "rxjs/ajax";

const totoroFilmData$ = ajax.getJSON(
  "https://ghibliapi.herokuapp.com/films/58611129-2dbc-4a81-a72f-77ddfc1b1b49"
);

const charmanderData$ = ajax.getJSON("https://pokeapi.co/api/v2/pokemon/4");

concat(totoroFilmData$, charmanderData$).subscribe(console.log);
// Salida: {..., title: 'My Neighbor Totoro', ...}, { abilities: [], ...}
```

**`merge` se suscribe de forma concurrente (a la vez) a todos los Observables de entrada, mientras que `concat` se suscribe a ellos por orden, y hasta que el primero no se complete, no se suscribe al siguiente. Comparación entre `concat` y `merge`:**

[StackBlitz](https://stackblitz.com/edit/docu-rxjs-merge-2?file=index.ts)

```javascript
import { concat, merge, timer } from "rxjs";
import { mapTo } from "rxjs/operators";

const first$ = timer(3000).pipe(mapTo("Primero"));

const second$ = timer(1000).pipe(mapTo("Segundo"));

const third$ = timer(2000).pipe(mapTo("Tercero"));

merge(first$, second$, third$).subscribe(console.log);
// Salida: (1s) Segundo (1s) Tercero (1s) Primero

concat(first$, second$, third$).subscribe(console.log);
// Salida: (3s) Primero (1s) Segundo (2s) Tercero
```

### Ejemplos de la documentación oficial

**Unir 2 Observables: 1s interval y clicks**

```javascript
import { merge, fromEvent, interval } from "rxjs";

const clicks = fromEvent(document, "click");
const timer = interval(1000);
const clicksOrTimer = merge(clicks, timer);
clicksOrTimer.subscribe((x) => console.log(x));

// Salida:
// timer emite valores ascendetntes, uno cada segundo (1000ms)
// clicks imprime MouseEvents por console cada vez que se haga click en el 'document'
```

**Unir 3 Observables, pero solo ejecutar 2 de forma concurrente**

```javascript
import { merge, interval } from "rxjs";
import { take } from "rxjs/operators";

const timer1 = interval(1000).pipe(take(10));
const timer2 = interval(2000).pipe(take(6));
const timer3 = interval(500).pipe(take(10));
const concurrent = 2; // el argumento
const merged = merge(timer1, timer2, timer3, concurrent);
merged.subscribe((x) => console.log(x));

// Salida:
// - timer1 y timer2 se ejecutan concurrentemente
// - timer1 emite un valor cada 1000ms durante 10 iterations
// - timer2 emite un valor cada 2000ms durante 6 iterations
// - Cuando timer1 llega a su max iteration, timer2 continuará
//   y timer3 empezará a ejecutarse concurrentemente con timer2
// - Cuando timer2 llega a su max iteration, se termina, y
//   timer3 continuará emitiendo un valor cada 500ms hasta que se complete
```

<details>

<summary>Sobrecargas</summary>

#### Firma

`merge(v1: any, scheduler: SchedulerLike): Observable<T>`

#### Parámetros

#### Retorna

`Observable<T>`

#### Firma

`merge(v1: any, concurrent: number, scheduler: SchedulerLike): Observable<T>`

#### Parámetros

#### Retorna

`Observable<T>`

#### Firma

`merge(v1: any, v2: any, scheduler: SchedulerLike): Observable<T | T2>`

#### Parámetros

#### Retorna

`Observable<T | T2>`

#### Firma

`merge(v1: any, v2: any, concurrent: number, scheduler: SchedulerLike): Observable<T | T2>`

#### Parámetros

#### Retorna

`Observable<T | T2>`

#### Firma

`merge(v1: any, v2: any, v3: any, scheduler: SchedulerLike): Observable<T | T2 | T3>`

#### Parámetros

#### Retorna

`Observable<T | T2 | T3>`

#### Firma

`merge(v1: any, v2: any, v3: any, concurrent: number, scheduler: SchedulerLike): Observable<T | T2 | T3>`

#### Parámetros

#### Retorna

`Observable<T | T2 | T3>`

#### Firma

`merge(v1: any, v2: any, v3: any, v4: any, scheduler: SchedulerLike): Observable<T | T2 | T3 | T4>`

#### Parámetros

#### Retorna

`Observable<T | T2 | T3 | T4>`

#### Firma

`merge(v1: any, v2: any, v3: any, v4: any, concurrent: number, scheduler: SchedulerLike): Observable<T | T2 | T3 | T4>`

#### Parámetros

#### Retorna

`Observable<T | T2 | T3 | T4>`

#### Firma

`merge(v1: any, v2: any, v3: any, v4: any, v5: any, scheduler: SchedulerLike): Observable<T | T2 | T3 | T4 | T5>`

#### Parámetros

#### Retorna

`Observable<T | T2 | T3 | T4 | T5>`

#### Firma

`merge(v1: any, v2: any, v3: any, v4: any, v5: any, concurrent: number, scheduler: SchedulerLike): Observable<T | T2 | T3 | T4 | T5>`

#### Parámetros

#### Retorna

`Observable<T | T2 | T3 | T4 | T5>`

#### Firma

`merge(v1: any, v2: any, v3: any, v4: any, v5: any, v6: any, scheduler: SchedulerLike): Observable<T | T2 | T3 | T4 | T5 | T6>`

#### Parámetros

#### Retorna

`Observable<T | T2 | T3 | T4 | T5 | T6>`

#### Firma

merge(v1: any, v2: any, v3: any, v4: any, v5: any, v6: any, concurrent: number, scheduler: SchedulerLike): Observable\<T | T2 | `T3 | T4 | T5 | T6>`

#### Parámetros

#### Retorna

`Observable<T | T2 | T3 | T4 | T5 | T6>`

#### Firma

`merge(v1: any): Observable<T>`

#### Parámetros

#### Retorna

`Observable<T>`

#### Firma

`merge(v1: any, concurrent?: number): Observable<T>`

#### Parámetros

#### Retorna

`Observable<T>`

#### Firma

`merge(v1: any, v2: any): Observable<T | T2>`

#### Parámetros

#### Retorna

`Observable<T | T2>`

#### Firma

`merge(v1: any, v2: any, concurrent?: number): Observable<T | T2>`

#### Parámetros

#### Retorna

`Observable<T | T2>`

#### Firma

`merge(v1: any, v2: any, v3: any): Observable<T | T2 | T3>`

#### Parámetros

#### Retorna

`Observable<T | T2 | T3>`

#### Firma

`merge(v1: any, v2: any, v3: any, concurrent?: number): Observable<T | T2 | T3>`

#### Parámetros

#### Retorna

`Observable<T | T2 | T3>`

#### Firma

`merge(v1: any, v2: any, v3: any, v4: any): Observable<T | T2 | T3 | T4>`

#### Parámetros

#### Retorna

`Observable<T | T2 | T3 | T4>`

#### Firma

`merge(v1: any, v2: any, v3: any, v4: any, concurrent?: number): Observable<T | T2 | T3 | T4>`

#### Parámetros

#### Retorna

`Observable<T | T2 | T3 | T4>`

#### Firma

`merge(v1: any, v2: any, v3: any, v4: any, v5: any): Observable<T | T2 | T3 | T4 | T5>`

#### Parámetros

#### Retorna

`Observable<T | T2 | T3 | T4 | T5>`

#### Firma

`merge(v1: any, v2: any, v3: any, v4: any, v5: any, concurrent?: number): Observable<T | T2 | T3 | T4 | T5>`

#### Parámetros

#### Retorna

`Observable<T | T2 | T3 | T4 | T5>`

#### Firma

`merge(v1: any, v2: any, v3: any, v4: any, v5: any, v6: any): Observable<T | T2 | T3 | T4 | T5 | T6>`

#### Parámetros

#### Retorna

`Observable<T | T2 | T3 | T4 | T5 | T6>`

#### Firma

`merge(v1: any, v2: any, v3: any, v4: any, v5: any, v6: any, concurrent?: number): Observable<T | T2 | T3 | T4 | T5 | T6>`

#### Parámetros

#### Retorna

`Observable<T | T2 | T3 | T4 | T5 | T6>`

#### Firma

`merge(...observables: any[]): Observable<T>`

#### Parámetros

#### Retorna

`Observable<T>`

#### Firma

`merge(...observables: any[]): Observable<T>`

#### Parámetros

#### Retorna

`Observable<T>`

#### Firma

`merge(...observables: any[]): Observable<R>`

#### Parámetros

#### Retorna

`Observable<R>`

#### Firma

`merge(...observables: any[]): Observable<R>`

#### Parámetros

#### Retorna

`Observable<R>`

</details>

### Recursos adicionales

[![Source code](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/combination/assets/icons/source-code.png)](https://github.com/ReactiveX/rxjs/blob/master/src/internal/observable/merge.ts)

[Documentación oficial en inglés](https://rxjs.dev/api/index/function/merge)


# mergeAll

Convierte un Observable de orden superior en uno de primer orden que emite las emisiones de los Observables internos de forma concurrente

<details>

<summary>Signatura</summary>

#### Firma

`mergeAll<T>(concurrent: number = Number.POSITIVE_INFINITY): OperatorFunction<ObservableInput<T>, T>`

#### Parámetros

#### Retorna

`OperatorFunction<ObservableInput<T>, T>`: Un Observable que emite los valores de todos los Observables internos que emita el Observable fuente.

</details>

## Descripción

Convierte un Observable de orden superior en uno de primer orden.

![Diagrama de canicas del operador mergeAll](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/combination/assets/images/marble-diagrams/join-creation/mergeAll.png)

`mergeAll` se suscribe a un Observable que emite Observables, también conocido como Observable de orden superior. Cada vez que observa la emisión de uno de los Observables internos, se suscribe a él y emite todos los valores del Observable interno en el Observable resultante. El Observable resultante se completa cuando todos los Observables internos se hayan completado.

Cualquier error que se produzca en uno de los Observables internos se emite de forma inmediata en el Observable resultante.

## Ejemplos

**Realizar todas las peticiones AJAX de forma concurrente (en paralelo)**

[StackBlitz](https://stackblitz.com/edit/docu-rxjs-mergeall?file=index.ts)

```javascript
import { mergeAll, map, delay } from "rxjs/operators";
import { ajax } from "rxjs/ajax";
import { of } from "rxjs";

const pokemonId$ = of(1, 5, 6);

function getPokemonName(id: number) {
  return ajax.getJSON(`https://pokeapi.co/api/v2/pokemon/${id}`).pipe(
    map(({ name }) => name),
    delay(2000)
  );
}

pokemonId$
  .pipe(
    map((id) => getPokemonName(id)),
    mergeAll()
  )
  .subscribe(console.log);
// Salida: (2s) bulbasaur, charmeleon, charizard
```

**Realizar como mucho dos peticiones AJAX de forma concurrente**

[StackBlitz](https://stackblitz.com/edit/docu-rxjs-mergeall-2?file=index.ts)

```javascript
import { mergeAll, map, delay } from "rxjs/operators";
import { ajax } from "rxjs/ajax";
import { of } from "rxjs";

const pokemonId$ = of(1, 5, 6);

function getPokemonName(id: number) {
  return ajax.getJSON(`https://pokeapi.co/api/v2/pokemon/${id}`).pipe(
    map(({ name }) => name),
    delay(2000)
  );
}

const maxConcurrent = 2;

pokemonId$
  .pipe(
    map((id) => getPokemonName(id)),
    mergeAll(maxConcurrent)
  )
  .subscribe(console.log);
// Salida: (2s) bulbasaur, charmeleon (2s) charizard
```

### Ejemplos de la documentación oficial

**Generar un Observable intervalo por cada evento click, y unir sus emisiones en un solo Observable**

```javascript
import { fromEvent, interval } from "rxjs";
import { map, mergeAll } from "rxjs/operators";

const clicks = fromEvent(document, "click");
const higherOrder = clicks.pipe(map((ev) => interval(1000)));
const firstOrder = higherOrder.pipe(mergeAll());
firstOrder.subscribe((x) => console.log(x));
```

**Emitir los números del 0 al 9 a intervalos de un segundo por cada click, permitiendo únicamente 2 temporizadores concurrentes**

```javascript
import { fromEvent, interval } from "rxjs";
import { take, map, mergeAll } from "rxjs/operators";

const clicks = fromEvent(document, "click");
const higherOrder = clicks.pipe(map((ev) => interval(1000).pipe(take(10))));
const firstOrder = higherOrder.pipe(mergeAll(2));
firstOrder.subscribe((x) => console.log(x));
```

### Recursos adicionales

[![Source code](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/combination/assets/icons/source-code.png)](https://github.com/ReactiveX/rxjs/blob/master/src/internal/operators/mergeAll.ts)

[Documentación oficial en inglés](https://rxjs.dev/api/operators/mergeAll)


# race

Retorna un Observable que refleja al primer Observable que emita un valor

<details>

<summary>Signatura</summary>

#### Firma

`race<T>(...observables: any[]): Observable<T>`

#### Parámetros

#### Retorna

`Observable<T>`: Un Observable que refleja las emisiones del primer Observable que emita un valor.

</details>

## Descripción

Refleja las emisiones del primer Observable que emita un valor.

## Ejemplos

**Hacer una carrera con 3 Observables**

[StackBlitz](https://stackblitz.com/edit/docu-rxjs-race?file=index.html\))

```javascript
import { mapTo } from "rxjs/operators";
import { race, timer } from "rxjs";

const slow$ = timer(5000).pipe(mapTo("Caracol"));
const medium$ = timer(3000).pipe(mapTo("Gatito"));
const fast$ = timer(2000).pipe(mapTo("Guepardo"));

//
race(slow$, medium$, fast$).subscribe((winner) =>
  console.log(`Y el ganador es... ¡${winner}!`)
);
// Salida: Y el ganador es... ¡Guepardo!
```

**Advertencia: Si alguno de los Observables lanza un error, la 'carrera' terminará con un error**

[StackBlitz](https://stackblitz.com/edit/docu-rxjs-race-2?file=index.ts)

```javascript
import { mapTo } from "rxjs/operators";
import { race, timer, throwError } from "rxjs";

const slow$ = timer(5000).pipe(mapTo("Caracol"));
const medium$ = timer(3000).pipe(mapTo("Gatito"));
const fast$ = timer(2000).pipe(mapTo("Guepardo"));

const error$ = throwError("¡Oh no!");

race(slow$, medium$, fast$, error$).subscribe(console.log, console.error);
// Salida: (error) ¡Oh no!
```

### Ejemplo de la documentación oficial

**Reflejar al primer Observable que emita un valor**

```javascript
import { race, interval } from "rxjs";
import { mapTo } from "rxjs/operators";

const obs1 = interval(1000).pipe(mapTo("Rápido"));
const obs2 = interval(3000).pipe(mapTo("Velocidad media"));
const obs3 = interval(5000).pipe(mapTo("Lento"));

race(obs3, obs1, obs2).subscribe((winner) => console.log(winner));

// Salida:
// Emite 'Rápido' cada segundo
```

<details>

<summary>Sobrecargas</summary>

#### Firma

`race(arg: [any]): Observable<A>`

#### Parámetros

#### Retorna

`Observable<A>`

#### Firma

`race(arg: [any, any]): Observable<A | B>`

#### Parámetros

#### Retorna

`Observable<A | B>`

#### Firma

`race(arg: [any, any, any]): Observable<A | B | C>`

#### Parámetros

#### Retorna

`Observable<A | B | C>`

#### Firma

`race(arg: [any, any, any, any]): Observable<A | B | C | D>`

#### Parámetros

#### Retorna

`Observable<A | B | C | D>`

#### Firma

`race(arg: [any, any, any, any, any]): Observable<A | B | C | D | E>`

#### Parámetros

#### Retorna

`Observable<A | B | C | D | E>`

#### Firma

`race(arg: any[]): Observable<T>`

#### Parámetros

#### Retorna

`Observable<T>`

#### Firma

`race(arg: any[]): Observable<{}>`

#### Parámetros

#### Retorna

`Observable<{}>`

#### Firma

`race(a: any): Observable<A>`

#### Parámetros

#### Retorna

`Observable<A>`

#### Firma

`race(a: any, b: any): Observable<A | B>`

#### Parámetros

#### Retorna

`Observable<A | B>`

#### Firma

`race(a: any, b: any, c: any): Observable<A | B | C>`

#### Parámetros

#### Retorna

`Observable<A | B | C>`

#### Firma

`race(a: any, b: any, c: any, d: any): Observable<A | B | C | D>`

#### Parámetros

#### Retorna

`Observable<A | B | C | D>`

#### Firma

`race(a: any, b: any, c: any, d: any, e: any): Observable<A | B | C | D | E>`

#### Parámetros

#### Retorna

`Observable<A | B | C | D | E>`

#### Firma

`race(observables: any[]): Observable<T>`

#### Parámetros

#### Retorna

`Observable<T>`

#### Firma

`race(observables: any[]): Observable<{}>`

#### Parámetros

#### Retorna

`Observable<{}>`

#### Firma

`race(...observables: any[]): Observable<T>`

#### Parámetros

#### Retorna

`Observable<T>`

#### Firma

`race(...observables: any[]): Observable<{}>`

#### Parámetros

#### Retorna

`Observable<{}>`

</details>

### Recursos adicionales

[![Source code](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/combination/assets/icons/source-code.png)](https://github.com/ReactiveX/rxjs/blob/master/src/internal/observable/race.ts)

* [Documentación oficial en inglés](https://rxjs.dev/api/index/function/race)


# startWith

Emite los elementos que se especifiquen como argumentos antes de empezar a emitir las emisiones del Observable fuente

<details>

<summary>Signatura</summary>

#### Firma

`startWith<T, D>(...array: (SchedulerLike | T)[]): OperatorFunction<T, T | D>`

#### Parámetros

#### Retorna

`OperatorFunction<T, T | D>`: Un Observable que emite primero los elementos en el `Iterable` especificado, y después emite los valores emitidos por el Observable fuente.

</details>

## Descripción

Primero emite sus argumentos en orden, y después las emisiones de la fuente.

![Diagrama de canicas del operador startWith](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/combination/assets/images/marble-diagrams/join-creation/startWith.png)

## Ejemplos

**Proporcionar un valor inicial al flujo de emisiones**

[StackBlitz](https://stackblitz.com/edit/docu-rxjs-startwith?file=index.ts)

```javascript
import { startWith } from "rxjs/operators";
import { from } from "rxjs";

const fruit$ = from(["Fresa", "Cereza"]);

fruit$.pipe(startWith("Arándano")).subscribe(console.log);
// Salida: Arándano, Fresa, Cereza
```

**A startWith se le puede proporcionar más de un valor**

[StackBlitz](https://stackblitz.com/edit/docu-rxjs-startwith-2?file=index.ts)

```javascript
import { startWith } from "rxjs/operators";
import { range } from "rxjs";

const number$ = range(0, 4);

number$.pipe(startWith(-3, -2, -1)).subscribe(console.log);
// Salida: -3, -2, -1, 0, 1, 2, 3
```

### Ejemplo de la documentación oficial

**Comenzar la cadena de emisiones con 'primero' y 'segundo'**

```javascript
import { of } from "rxjs";
import { startWith } from "rxjs/operators";

of("Valores de la fuente")
  .pipe(startWith("Primero", "Segundo"))
  .subscribe((x) => console.log(x));

// Salida: "Primero", "Segundo", "Valores de la fuente"
```

<details>

<summary>Sobrecargas</summary>

#### Firma

`startWith(scheduler: SchedulerLike): MonoTypeOperatorFunction<T>`

#### Parámetros

#### Retorna

`MonoTypeOperatorFunction<T>`

#### Firma

`startWith(v1: D, scheduler: SchedulerLike): OperatorFunction<T, T | D>`

#### Parámetros

#### Retorna

`OperatorFunction<T, T | D>`

#### Firma

`startWith(v1: D, v2: E, scheduler: SchedulerLike): OperatorFunction<T, T | D | E>`

#### Parámetros

#### Retorna

`OperatorFunction<T, T | D | E>`

#### Firma

`startWith(v1: D, v2: E, v3: F, scheduler: SchedulerLike): OperatorFunction<T, T | D | E | F>`

#### Parámetros

#### Retorna

`OperatorFunction<T, T | D | E | F>`

#### Firma

`startWith(v1: D, v2: E, v3: F, v4: G, scheduler: SchedulerLike): OperatorFunction<T, T | D | E | F | G>`

#### Parámetros

#### Retorna

OperatorFunction\<T, T | D | E | F | G>

#### Firma

`startWith(v1: D, v2: E, v3: F, v4: G, v5: H, scheduler: SchedulerLike): OperatorFunction<T, T | D | E | F | G | H>`

#### Parámetros

#### Retorna

OperatorFunction\<T, T | D | E | F | G | H>

#### Firma

`startWith(v1: D, v2: E, v3: F, v4: G, v5: H, v6: I, scheduler: SchedulerLike): OperatorFunction<T, T | D | E | F | G | H | I>`

#### Parámetros

#### Retorna

`OperatorFunction<T, T | D | E | F | G | H | I>`

#### Firma

`startWith(v1: D): OperatorFunction<T, T | D>`

#### Parámetros

#### Retorna

`OperatorFunction<T, T | D>`

#### Firma

`startWith(v1: D, v2: E): OperatorFunction<T, T | D | E>`

#### Parámetros

#### Retorna

`OperatorFunction<T, T | D | E>`

#### Firma

`startWith(v1: D, v2: E, v3: F): OperatorFunction<T, T | D | E | F>`

#### Parámetros

#### Retorna

`OperatorFunction<T, T | D | E | F>`

#### Firma

`startWith(v1: D, v2: E, v3: F, v4: G): OperatorFunction<T, T | D | E | F | G>`

#### Parámetros

#### Retorna

`OperatorFunction<T, T | D | E | F | G>`

#### Firma

`startWith(v1: D, v2: E, v3: F, v4: G, v5: H): OperatorFunction<T, T | D | E | F | G | H>`

#### Parámetros

#### Retorna

`OperatorFunction<T, T | D | E | F | G | H>`

#### Firma

`startWith(v1: D, v2: E, v3: F, v4: G, v5: H, v6: I): OperatorFunction<T, T | D | E | F | G | H | I>`

#### Parámetros

#### Retorna

`OperatorFunction<T, T | D | E | F | G | H | I>`

#### Firma

`startWith(...array: D[]): OperatorFunction<T, T | D>`

#### Parámetros

#### Retorna

`OperatorFunction<T, T | D>`

#### Firma

`startWith(...array: (SchedulerLike | D)[]): OperatorFunction<T, T | D>`

#### Parámetros

#### Retorna

`OperatorFunction<T, T | D>`

</details>

### Recursos adicionales

[![Source code](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/combination/assets/icons/source-code.png)](https://github.com/ReactiveX/rxjs/blob/master/src/internal/operators/startWith.ts)

[Documentación oficial en inglés](https://rxjs.dev/api/operators/startWith)


# switchAll

Convierte un Observable de orden superior en uno de primer orden, produciendo valores únicamente de la secuencia Observable más reciente

<details>

<summary>Signatura</summary>

#### Firma

`switchAll<T>(): OperatorFunction<ObservableInput<T>, T>`

#### Parámetros

No recibe ningún parámetro.

#### Retorna

`OperatorFunction<ObservableInput<T>, T>`

</details>

## Descripción

Convierte un Observable de orden superior en uno de primer orden.

![Diagrama de canicas del operador switchAll](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/combination/assets/images/marble-diagrams/join-creation/switchAll.png)

switchAll se suscribe a un Observable de Observables, también conocido como un "Observable de orden superior" (o `Observable<Observable<T>>`.) Se suscribe al 'Observable interno' emitido por la fuente más reciente, cancelando la suscripción al Observable interno anterior, de manera que únicamente puede haber una suscripción a un Observable interno: al más reciente. El Observable resultante retornado por switchAll solo se completa si el Observable fuente se completa, y si el Observable interno suscrito también se completa.

## Ejemplos

### Ejemplo de la documentación oficial

**Generar un Observable intervalo nuevo con cada click**

Con cada nuevo click, el intervalo anterior se cancela y el nuevo intervalo es suscrito.

```javascript
import { fromEvent, interval } from "rxjs";
import { switchAll, map, tap } from "rxjs/operators";

const clicks = fromEvent(document, "click").pipe(
  tap(() => console.log("click"))
);
const source = clicks.pipe(map((ev) => interval(1000)));

source.pipe(switchAll()).subscribe((x) => console.log(x));

// Salida: (click) 1, 2, 3, 4... (click) 1, 2, 3... (click) ...
```

### Recursos adicionales

[![Source code](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/combination/assets/icons/source-code.png)](https://github.com/ReactiveX/rxjs/blob/master/src/internal/operators/switchAll.ts)

[Documentación oficial en inglés](https://rxjs.dev/api/operators/switchAll)


# withLatestFrom

Combina el Observable fuente con otros Observables para crear un Observable cuyas emisiones se calculan a partir de los valores más recientes de cada uno, cada vez que la fuente emite

<details>

<summary>Signatura</summary>

#### Firma

`withLatestFrom<T, R>(...args: any[]): OperatorFunction<T, R>`

#### Parámetros

#### Retorna

`OperatorFunction<T, R>`: Un Observable de valores proyectados de cada Observable *input*, o un array de los valores más recientes de cada Observable *input*.

</details>

## Descripción

Cuando el Observable fuente emite un valor, combina dicho valor con las emisiones más recientes de los demás Observables, y emite el resultado de dicha combinación.

![Diagrama de canicas del operador withLatestFrom](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/combination/assets/images/marble-diagrams/join-creation/withLatestFrom.png)

`withLatestFrom` combina cada valor del Observable fuente (la instancia) con los valores más recientes de los demás Observables cada vez que la fuente emite un valor. Opcionalmente, se puede utilizar una función de proyección para determinar el valor que se emite en el Observable resultante. Todos los Observables *input* deben emitir al menos un valor para que el Observable resultante pueda emitir.

## Ejemplos

**Combinar cada tecla pulsada con un Observable intervalo, para saber en qué momento se pulsa cada tecla**

[StackBlitz](https://stackblitz.com/edit/docu-rxjs-withlatestfrom?file=index.ts)

```javascript
import { fromEvent, interval } from "rxjs";
import { withLatestFrom, map } from "rxjs/operators";

const key$ =
  fromEvent <
  KeyboardEvent >
  (document, "keydown").pipe(map(({ code }) => code));

const number$ = interval(1000);

key$
  .pipe(
    withLatestFrom(number$),
    map(([code, time]) => `Tecla ${code} pulsada a los ${time} segundos`)
  )
  .subscribe((x) => console.log(x));
// Salida: (2s) Tecla KeyR pulsada a los 2 segundos (1s) Tecla KeyX pulsada a los 3 segundos...
```

### Ejemplo de la documentación oficial

**Emitir un array con el temporizador más reciente más el evento click, en cada click**

```javascript
import { fromEvent, interval } from "rxjs";
import { withLatestFrom } from "rxjs/operators";

const clicks = fromEvent(document, "click");
const timer = interval(1000);
const result = clicks.pipe(withLatestFrom(timer));
result.subscribe((x) => console.log(x));
```

<details>

<summary>Sobrecargas</summary>

#### Firma

`withLatestFrom(project: (v1: T) => R): OperatorFunction<T, R>`

#### Parámetros

#### Retorna

`OperatorFunction<T, R>`

#### Firma

`withLatestFrom(source2: O2, project: (v1: T, v2: ObservedValueOf<O2>) => R): OperatorFunction<T, R>`

#### Parámetros

#### Retorna

`OperatorFunction<T, R>`

#### Firma

`withLatestFrom(v2: O2, v3: O3, project: (v1: T, v2: ObservedValueOf<O2>, v3: ObservedValueOf<O3>) => R): OperatorFunction<T, R>`

#### Parámetros

#### Retorna

`OperatorFunction<T, R>`

#### Firma

`withLatestFrom(v2: O2, v3: O3, v4: O4, project: (v1: T, v2: ObservedValueOf<O2>, v3: ObservedValueOf<O3>, v4: ObservedValueOf<O4>) => R): OperatorFunction<T, R>`

#### Parámetros

#### Retorna

`OperatorFunction<T, R>`

#### Firma

`withLatestFrom(v2: O2, v3: O3, v4: O4, v5: O5, project: (v1: T, v2: ObservedValueOf<O2>, v3: ObservedValueOf<O3>, v4: ObservedValueOf<O4>, v5: ObservedValueOf<O5>) => R): OperatorFunction<T, R>`

#### Parámetros

#### Retorna

`OperatorFunction<T, R>`

#### Firma

`withLatestFrom(v2: O2, v3: O3, v4: O4, v5: O5, v6: O6, project: (v1: T, v2: ObservedValueOf<O2>, v3: ObservedValueOf<O3>, v4: ObservedValueOf<O4>, v5: ObservedValueOf<O5>, v6: ObservedValueOf<O6>) => R): OperatorFunction<T, R>`

#### Parámetros

#### Retorna

`OperatorFunction<T, R>`

#### Firma

`withLatestFrom(source2: O2): OperatorFunction<T, [T, ObservedValueOf<O2>]>`

#### Parámetros

#### Retorna

`OperatorFunction<T, [T, ObservedValueOf<O2>]>`

#### Firma

`withLatestFrom(v2: O2, v3: O3): OperatorFunction<T, [T, ObservedValueOf<O2>, ObservedValueOf<O3>]>`

#### Parámetros

#### Retorna

`OperatorFunction<T, [T, ObservedValueOf<O2>, ObservedValueOf<O3>]>`

#### Firma

`withLatestFrom(v2: O2, v3: O3, v4: O4): OperatorFunction<T, [T, ObservedValueOf<O2>, ObservedValueOf<O3>, ObservedValueOf<O4>]>`

#### Parámetros

#### Retorna

`OperatorFunction<T, [T, ObservedValueOf<O2>, ObservedValueOf<O3>, ObservedValueOf<O4>]>`

#### Firma

`withLatestFrom(v2: O2, v3: O3, v4: O4, v5: O5): OperatorFunction<T, [T, ObservedValueOf<O2>, ObservedValueOf<O3>, ObservedValueOf<O4>, ObservedValueOf<O5>]>`

#### Parámetros

#### Retorna

`OperatorFunction<T, [T, ObservedValueOf<O2>, ObservedValueOf<O3>, ObservedValueOf<O4>, ObservedValueOf<O5>]>`

#### Firma

`withLatestFrom(v2: O2, v3: O3, v4: O4, v5: O5, v6: O6): OperatorFunction<T, [T, ObservedValueOf<O2>, ObservedValueOf<O3>, ObservedValueOf<O4>, ObservedValueOf<O5>, ObservedValueOf<O6>]>`

#### Parámetros

#### Retorna

`OperatorFunction<T, [T, ObservedValueOf<O2>, ObservedValueOf<O3>, ObservedValueOf<O4>, ObservedValueOf<O5>, ObservedValueOf<O6>]>`

#### Firma

`withLatestFrom(...observables: any[]): OperatorFunction<T, R>`

#### Parámetros

#### Retorna

`OperatorFunction<T, R>`

#### Firma

`withLatestFrom(array: any[]): OperatorFunction<T, R>`

#### Parámetros

#### Retorna

`OperatorFunction<T, R>`

#### Firma

`withLatestFrom(array: any[], project: (...values: any[]) => R): OperatorFunction<T, R>`

#### Parámetros

#### Retorna

`OperatorFunction<T, R>`

</details>

### Recursos adicionales

[![Source code](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/combination/assets/icons/source-code.png)](https://github.com/ReactiveX/rxjs/blob/master/src/internal/operators/withLatestFrom.ts)

[Documentación oficial en inglés](https://rxjs.dev/api/operators/withLatestFrom)


# zip

Combina varios Observables para crear otro Observable cuyos valores se calculen a partir de las emisiones, en orden, de cada uno de sus Observables de entrada

<details>

<summary>Signatura</summary>

#### Firma

`zip<O extends ObservableInput<any>, R>(...observables: (O | ((...values: ObservedValueOf<O>[]) => R))[]): Observable<ObservedValueOf<O>[] | R>`

#### Parámetros

#### Retorna

`Observable<ObservedValueOf<O>[] | R>`

</details>

## Descripción

Si el último parámetro es una función, esta se utiliza para computar el valor creado a partir de los valores de entrada. Si no, se retorna un array de los valores de entrada.

## Ejemplos

**Esperar a que dos Observables emitan un valor, y emitir ambos valores en un array**

[StackBlitz](https://stackblitz.com/edit/docu-rxjs-zip?file=index.ts)

```javascript
import { zip, timer } from "rxjs";
import { mapTo } from "rxjs/operators";

const hello$ = timer(2000).pipe(mapTo("Hello"));
const world$ = timer(4000).pipe(mapTo("World"));

zip(hello$, world$).subscribe(console.log);
// Salida: ['Hello', 'World']
```

**Al combinarlo con interval (o timer), zip puede utilizarse para emitir los valores de un Observable cada cierto tiempo.** **Ej: Emitir una cadena cada vez que interval emite (cada segundo)**

[StackBlitz](https://stackblitz.com/edit/docu-rxjs-zip-2?file=index.ts)

```javascript
import { from, interval, zip } from "rxjs";
import { map } from "rxjs/operators";

const framework$ = zip(from(["Angular", "React", "Vue"]), interval(1000)).pipe(
  map(([framework]) => framework)
);

framework$.subscribe(console.log);
// Salida: (1s) Angular (1s) React (1s) Vue
```

### Ejemplo de la documentación oficial

**Combinar la edad y el nombre de distintas fuentes**

```javascript
import { zip, of } from "rxjs";
import { map } from "rxjs/operators";

let age$ = of < number > (27, 25, 29);
let name$ = of < string > ("Foo", "Bar", "Beer");
let isDev$ = of < boolean > (true, true, false);

zip(age$, name$, isDev$)
  .pipe(map(([age, name, isDev]) => ({ age, name, isDev })))
  .subscribe((x) => console.log(x));

// Salida
// { age: 27, name: 'Foo', isDev: true }
// { age: 25, name: 'Bar', isDev: true }
// { age: 29, name: 'Beer', isDev: false }
```

<details>

<summary>Sobrecargas</summary>

#### Firma

`zip(v1: O1, resultSelector: (v1: ObservedValueOf<O1>) => R): Observable<R>`

#### Parámetros

#### Retorna

`Observable<R>`

#### Firma

`zip(v1: O1, v2: O2, resultSelector: (v1: ObservedValueOf<O1>, v2: ObservedValueOf<O2>) => R): Observable<R>`

#### Parámetros

#### Retorna

`Observable<R>`

#### Firma

`zip(v1: O1, v2: O2, v3: O3, resultSelector: (v1: ObservedValueOf<O1>, v2: ObservedValueOf<O2>, v3: ObservedValueOf<O3>) => R): Observable<R>`

#### Parámetros

#### Retorna

`Observable<R>`

#### Firma

`zip(v1: O1, v2: O2, v3: O3, v4: O4, resultSelector: (v1: ObservedValueOf<O1>, v2: ObservedValueOf<O2>, v3: ObservedValueOf<O3>, v4: ObservedValueOf<O4>) => R): Observable<R>`

#### Parámetros

#### Retorna

`Observable<R>`

#### Firma

`zip(v1: O1, v2: O2, v3: O3, v4: O4, v5: O5, resultSelector: (v1: ObservedValueOf<O1>, v2: ObservedValueOf<O2>, v3: ObservedValueOf<O3>, v4: ObservedValueOf<O4>, v5: ObservedValueOf<O5>) => R): Observable<R>`

#### Parámetros

#### Retorna

`Observable<R>`

#### Firma

`zip(v1: O1, v2: O2, v3: O3, v4: O4, v5: O5, v6: O6, resultSelector: (v1: ObservedValueOf<O1>, v2: ObservedValueOf<O2>, v3: ObservedValueOf<O3>, v4: ObservedValueOf<O4>, v5: ObservedValueOf<O5>, v6: ObservedValueOf<O6>) => R): Observable<R>`

#### Parámetros

#### Retorna

`Observable<R>`

#### Firma

`zip(v1: O1, v2: O2): Observable<[ObservedValueOf<O1>, ObservedValueOf<O2>]>`

#### Parámetros

#### Retorna

`Observable<[ObservedValueOf<O1>, ObservedValueOf<O2>]>`

#### Firma

`zip(v1: O1, v2: O2, v3: O3): Observable<[ObservedValueOf<O1>, ObservedValueOf<O2>, ObservedValueOf<O3>]>`

#### Parámetros

#### Retorna

`Observable<[ObservedValueOf<O1>, ObservedValueOf<O2>, ObservedValueOf<O3>]>`

#### Firma

`zip(v1: O1, v2: O2, v3: O3, v4: O4): Observable<[ObservedValueOf<O1>, ObservedValueOf<O2>, ObservedValueOf<O3>, ObservedValueOf<O4>]>`

#### Parámetros

#### Retorna

`Observable<[ObservedValueOf<O1>, ObservedValueOf<O2>, ObservedValueOf<O3>, ObservedValueOf<O4>]>`

#### Firma

zip(v1: O1, v2: O2, v3: O3, v4: O4, v5: O5): Observable<\[ObservedValueOf, ObservedValueOf, ObservedValueOf, `ObservedValueOf<O4>, ObservedValueOf<O5>]>`

#### Parámetros

#### Retorna

`Observable<[ObservedValueOf<O1>, ObservedValueOf<O2>, ObservedValueOf<O3>, ObservedValueOf<O4>, ObservedValueOf<O5>]>`

#### Firma

`zip(v1: O1, v2: O2, v3: O3, v4: O4, v5: O5, v6: O6): Observable<[ObservedValueOf<O1>, ObservedValueOf<O2>, ObservedValueOf<O3>, ObservedValueOf<O4>, ObservedValueOf<O5>, ObservedValueOf<O6>]>`

#### Parámetros

#### Retorna

`Observable<[ObservedValueOf<O1>, ObservedValueOf<O2>, ObservedValueOf<O3>, ObservedValueOf<O4>, ObservedValueOf<O5>, ObservedValueOf<O6>]>`

#### Firma

`zip(array: O[]): Observable<ObservedValueOf<O>[]>`

#### Parámetros

#### Retorna

`Observable<ObservedValueOf<O>[]>`

#### Firma

`zip(array: any[]): Observable<R>`

#### Parámetros

#### Retorna

`Observable<R>`

#### Firma

`zip(array: O[], resultSelector: (...values: ObservedValueOf<O>[]) => R): Observable<R>`

#### Parámetros

#### Retorna

`Observable<R>`

#### Firma

`zip(array: any[], resultSelector: (...values: any[]) => R): Observable<R>`

#### Parámetros

#### Retorna

`Observable<R>`

#### Firma

`zip(...observables: O[]): Observable<ObservedValueOf<O>[]>`

#### Parámetros

#### Retorna

`Observable<ObservedValueOf<O>[]>`

#### Firma

`zip(...observables: (O | ((...values: ObservedValueOf<O>[]) => R))[]): Observable<R>`

#### Parámetros

#### Retorna

`Observable<R>`

#### Firma

`zip(...observables: any[]): Observable<R>`

#### Parámetros

#### Retorna

`Observable<R>`

</details>

### Recursos adicionales

[![Source code](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/combination/assets/icons/source-code.png)](https://github.com/ReactiveX/rxjs/blob/master/src/internal/observable/zip.ts)

[Documentación oficial en inglés](https://rxjs.dev/api/index/function/zip)


# Condicional

* [defaultIfEmpty](/operadores/conditional/defaultifempty)
* [every](/operadores/conditional/every)
* [find](/operadores/conditional/find)
* [findIndex](/operadores/conditional/findindex)
* [isEmpty](/operadores/conditional/isempty)
* [sequenceEqual](/operadores/conditional/sequenceequal)


# defaultIfEmpty

Emite el valor proporcionado si el Observable fuente se completa sin emitir ningún valor. Si no, refleja al Observable fuente

<details>

<summary>Signatura</summary>

#### Firma

`defaultIfEmpty<T, R>(defaultValue: R = null): OperatorFunction<T, T | R>`

#### Parámetros

#### Retorna

`OperatorFunction<T, T | R>`: Un Observable que puede emitir el valor por defecto especificado si el Observable fuente no emite ningún valor, o los valores emitidos por el Observable fuente.

</details>

## Descripción

Si el Observable fuente está vacío, este operador emitirá un valor por defecto.

![Diagrama de canicas del operador defaultIfEmpty](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/conditional/assets/images/marble-diagrams/conditional-boolean/defaultIfEmpty.png)

`defaultIfEmpty` emite los valores emitidos por el Observable fuente o un valor por defecto en el caso de que el Observable fuente esté vacío (se completa sin haber emitido ningún valor `next`.)

## Ejemplos

**Como el Observable está vacío, se emitirá el valor por defecto**

[StackBlitz](https://stackblitz.com/edit/rxjs-defaultifempty-1?file=index.ts)

```javascript
import { defaultIfEmpty } from "rxjs/operators";
import { EMPTY } from "rxjs";

const empty$ = EMPTY;

empty$.pipe(defaultIfEmpty("La respuesta es 42")).subscribe(console.log);
// Salida: La respuesta es 42
```

**Si no se presiona ninguna tecla en 4 segundos, se emitirá el valor de la tecla por defecto**

[StackBlitz](https://stackblitz.com/edit/rxjs-defaultifempty-2?file=index.ts)

```typescript
import { defaultIfEmpty, map, takeUntil } from "rxjs/operators";
import { fromEvent, timer } from "rxjs";

const defaultKey = "Space";

const key$ = fromEvent<KeyboardEvent>(document, "keydown").pipe(
  map(({ code }) => code),
  takeUntil(timer(4000))
);

key$.pipe(defaultIfEmpty(defaultKey)).subscribe(console.log);
// Salida: (4s) Space
```

### Ejemplo de la documentación oficial

**Si en 5 segundos no se hace ningún click, se emitirá el mensaje "Ningún click"**

```javascript
import { fromEvent } from "rxjs";
import { defaultIfEmpty, takeUntil } from "rxjs/operators";

const clicks = fromEvent(document, "click");
const clicksBeforeFive = clicks.pipe(takeUntil(interval(5000)));
const result = clicksBeforeFive.pipe(defaultIfEmpty("Ningún click"));
result.subscribe((x) => console.log(x));
```

### Recursos adicionales

[![Source code](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/conditional/assets/icons/source-code.png)](https://github.com/ReactiveX/rxjs/blob/master/src/internal/operators/defaultIfEmpty.ts)

[Documentación oficial en inglés](https://rxjs.dev/api/operators/defaultIfEmpty)


# every

Retorna un Observable que emite un valor booleano que determina si todas las emisiones de la fuente cumplen o no una condición

<details>

<summary>Signatura</summary>

#### Firma

`every<T>(predicate: (value: T, index: number, source: Observable<T>) => boolean, thisArg?: any): OperatorFunction<T, boolean>`

#### Parámetros

#### Retorna

`OperatorFunction<T, boolean>`: Un Observable de un solo valor booleano que determina si todos los elementos del Observable fuente cumplen la condición especificada.

</details>

## Descripción

Si todos los valores emitidos por el Observable fuente cumplen la condición especificada, `every` emite *true*. Si hay algún valor que no cumpla la condición, se emite *false*.

## Ejemplos

**Comprobar si todos los valores emitidos son numéricos**

[StackBlitz](https://stackblitz.com/edit/rxjs-every-1?file=index.ts)

```javascript
import { of } from "rxjs";
import { every } from "rxjs/operators";

const number$ = of(1, 2, 3, 4);

number$.pipe(every((n) => Number.isInteger(n))).subscribe(console.log);
// Salida: true
```

**Comprobar si todos los valores emitidos son menores a 2**

[StackBlitz](https://stackblitz.com/edit/rxjs-every-2?file=index.ts)

```javascript
import { of } from "rxjs";
import { every } from "rxjs/operators";

const number$ = of(1, 2, 3, 4);

number$.pipe(every((n) => n < 2)).subscribe(console.log);
// Salida: false
```

**Comprobar si todas las peticiones tienen un status 200 (todo OK)**

[StackBlitz](https://stackblitz.com/edit/rxjs-every-3?file=index.ts)

```javascript
import { of } from "rxjs";
import { every, concatMap } from "rxjs/operators";
import { ajax } from "rxjs/ajax";

const pokemonId$ = of(1, 5, 6);

function getPokemon(id: number) {
  return ajax(`https://pokeapi.co/api/v2/pokemon/${id}`);
}

pokemonId$
  .pipe(
    concatMap((id) => getPokemon(id)),
    every(({ status }) => status === 200)
  )
  .subscribe(console.log);
// Salida: true
```

### Ejemplo de la documentación oficial

**Un simple ejemplo que emite&#x20;*****true*****&#x20;si todos los elementos son menores a 5,&#x20;*****false*****&#x20;en caso contrario**

```javascript
import { of } from "rxjs";
import { every } from "rxjs/operators";

of(1, 2, 3, 4, 5, 6)
  .pipe(every((x) => x < 5))
  .subscribe((x) => console.log(x)); // -> false
```

### Recursos adicionales

[![Source code](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/conditional/assets/icons/source-code.png)](https://github.com/ReactiveX/rxjs/blob/master/src/internal/operators/every.ts)

[Documentación oficial en inglés](https://rxjs.dev/api/operators/every)


# find

Emite únicamente el primer elemento emitido por el Observable fuente que cumpla una condición

💡 Si se quiere obtener el primer elemento emitido, sin que cumpla ninguna operación, se puede usar el operador [first](https://github.com/puntotech/rxjs-docu/blob/master/operators/filtering/first/README.md)

<details>

<summary>Signatura</summary>

#### Firma

`find<T>(predicate: (value: T, index: number, source: Observable<T>) => boolean, thisArg?: any): OperatorFunction<T, T | undefined>`

#### Parámetros

Opcional. El valor por defecto es `undefined`. Un argumento opcional para determinar el valor del `this` en la función `predicate`.

#### Retorna

`OperatorFunction<T, T | undefined>`: Un Observable del primer elemento que cumpla la condición.

</details>

## Descripción

Encuentra el primer valor que cumple una condición y lo emite.

![Diagrama de canicas del operador find](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/conditional/assets/images/marble-diagrams/conditional-boolean/find.png)

`find` busca el primer elemento del Observable fuente que cumpla la condición especificada en la función `predicate` y retorna la primera ocurrencia que exista en la fuente. Al contrario que el operador `first`, la función `predicate` es obligatoria, y no se emite un error si no se encuentra un valor válido.

## Ejemplos

**Emite la primera vez que se presiona la tecla X, y se completa el flujo**

[StackBlitz](https://stackblitz.com/edit/docu-rxjs-find?file=index.ts)

```typescript
import { find } from "rxjs/operators";
import { fromEvent } from "rxjs";

const key$ = fromEvent<KeyboardEvent>(document, "keydown");

key$.pipe(find(({ code }) => code === "KeyX")).subscribe(console.log);
// Salida: KeyboardEvent {}
```

**Emitir el primer lenguaje de tipo Multiparadigma**

Aunque haya más de un lenguaje de tipo multiparadigma, find emite únicamente el primero que encuentra.

[StackBlitz](https://stackblitz.com/edit/docu-rxjs-find-2?file=index.ts)

```javascript
import { find } from "rxjs/operators";
import { from } from "rxjs";

const language$ = from([
  { name: "Java", type: "Orientado a objetos" },
  { name: "Ruby", type: "Multiparadigma" },
  { name: "Haskell", type: "Funcional" },
  { name: "Rust", type: "Multiparadigma" },
]);

language$
  .pipe(find(({ type }) => type === "Multiparadigma"))
  .subscribe(console.log);
// Salida: { name: "Ruby", type: "Multiparadigma" }
```

**Si ningún elemento cumple la condición, se emite undefined**

[StackBlitz](https://stackblitz.com/edit/docu-rxjs-find-3?file=index.ts)

```javascript
import { find } from "rxjs/operators";
import { from } from "rxjs";

const user$ = from([
  { name: "Nya", language: "TS" },
  { name: "Juan", language: "JS" },
  { name: "Carlos", language: "Java" },
]);

user$
  .pipe(find(({ language }) => language === "PHP"))
  .subscribe(console.log, console.error, () =>
    console.log("¡Flujo completado!")
  );
// Salida: undefined, ¡Flujo completado!
```

### Ejemplo de la documentación oficial

**Encuentra y emite el primer click que ocurra en un elemento DIV**

```javascript
import { fromEvent } from "rxjs";
import { find } from "rxjs/operators";

const clicks = fromEvent(document, "click");
const result = clicks.pipe(find((ev) => ev.target.tagName === "DIV"));
result.subscribe((x) => console.log(x));
```

### Recursos adicionales

[![Source code](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/conditional/assets/icons/source-code.png)](https://github.com/ReactiveX/rxjs/blob/master/src/internal/operators/find.ts)

[Documentación oficial en inglés](https://rxjs.dev/api/operators/find)


# findIndex

Emite el índice del primer valor emitido por el Observable fuente que cumple una determinada condición

<details>

<summary>Signatura</summary>

#### Firma

`findIndex<T>(predicate: (value: T, index: number, source: Observable<T>) => boolean, thisArg?: any): OperatorFunction<T, number>`

#### Parámetros

#### Retorna

`OperatorFunction<T, number>`: Un Observable del índice del primer elemento que cumpla la condición.

</details>

## Descripción

Es como [find](https://github.com/puntotech/rxjs-docu/blob/master/operators/conditional/find/README.md), pero emite el índice del valor encontrado, en lugar del propio valor.

![Diagrama de canicas del operador findIndex](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/conditional/assets/images/marble-diagrams/conditional-boolean/findIndex.png)

findIndex busca el primer elemento del Observable fuente que cumpla la condición especificada en el predicado y retorna su índice (de base cero.) Al contrario que [first](https://github.com/puntotech/rxjs-docu/blob/master/operators/filtering/first/README.md), el predicado es obligatorio en findIndex, y tampoco emite un error si no encuentra un valor válido.

## Ejemplos

**Emitir el índice del primer lenguaje de tipo Multiparadigma**

[StackBlitz](https://stackblitz.com/edit/rxjs-findindex-1?file=index.ts)

```javascript
import { findIndex } from "rxjs/operators";
import { from } from "rxjs";

const language$ = from([
  { name: "Java", type: "Orientado a objetos" },
  { name: "Ruby", type: "Multiparadigma" },
  { name: "Haskell", type: "Funcional" },
  { name: "Rust", type: "Multiparadigma" },
]);

language$
  .pipe(findIndex(({ type }) => type === "Multiparadigma"))
  .subscribe(console.log);
// Salida: 1
```

**Emite el índice de la primera vez que se pulse la tecla x**

[StackBlitz](https://stackblitz.com/edit/rxjs-findindex-2?file=index.ts)

```typescript
import { findIndex, map } from "rxjs/operators";
import { fromEvent } from "rxjs";

const key$ = fromEvent<KeyboardEvent>(document, "keydown");

key$
  .pipe(
    map(({ code }) => code),
    findIndex((code) => code === "KeyX")
  )
  .subscribe(console.log);
// Salida: (Pulsar tecla n) (Pulsar tecla f) (Pulsar tecla x) 2
```

### Ejemplo de la documentación oficial

**Emite el índice del primer click que ocurre en un elemento DIV**

```javascript
import { fromEvent } from "rxjs";
import { findIndex } from "rxjs/operators";

const clicks = fromEvent(document, "click");
const result = clicks.pipe(findIndex((ev) => ev.target.tagName === "DIV"));
result.subscribe((x) => console.log(x));
```

### Recursos adicionales

[![Source code](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/conditional/assets/icons/source-code.png)](https://github.com/ReactiveX/rxjs/blob/master/src/internal/operators/findIndex.ts)

[Documentación oficial en inglés](https://rxjs.dev/api/operators/findIndex)


# isEmpty

Emite false si el Observable emite cualquier valor, o emite true si el Observable se completa sin emitir ningún valor

<details>

<summary>Signatura</summary>

#### Firma

`isEmpty<T>(): OperatorFunction<T, boolean>`

#### Parámetros

No recibe ningún parámetro.

#### Retorna

`OperatorFunction<T, boolean>`: Un Observable de valor booleano indicando si el Observable estaba vacío o no.

</details>

## Descripción

Indica si un Observable emite algún valor o no.

![Diagrama de canicas del operador isEmpty](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/conditional/assets/images/marble-diagrams/conditional-boolean/isEmpty.png)

`isEmpty` transforma un Observable que emite valores en un Observable que emite un solo valor booleano representando si el Observable fuente emite o no valores. En cuanto el Observable fuente emita un valor, `isEmpty` emitirá *false* y se completará. Si el Observable fuente se completa sin haber emitido ningún valor, `isEmpty` emitirá *true* y se completará.

Se podría lograr un efecto similar con el operador `count`, pero `isEmpty` puede emitir el valor *false* antes.

## Ejemplos

[StackBlitz](https://stackblitz.com/edit/rxjs-isempty?file=index.ts)

**Emite&#x20;*****false*****&#x20;para un Observable que no está vacío**

```javascript
import { of } from "rxjs";
import { isEmpty } from "rxjs/operators";

const word$ = of("No", "está", "vacío");

word$.pipe(isEmpty()).subscribe(console.log);
// Salida: false
```

**Emite&#x20;*****true*****&#x20;para Observables vacíos**

[StackBlitz](https://stackblitz.com/edit/rxjs-isempty-2?file=index.ts)

```javascript
import { EMPTY, of } from "rxjs";
import { isEmpty } from "rxjs/operators";

const empty$ = EMPTY;
const anotherEmpty$ = of();

empty$.pipe(isEmpty()).subscribe(console.log);
// Salida: true

anotherEmpty$.pipe(isEmpty()).subscribe(console.log);
// Salida: true
```

### Ejemplo de la documentación oficial

**Emite&#x20;*****false*****&#x20;para un Sujeto que no está vacío**

```javascript
    import { Subject } from 'rxjs';
    import { isEmpty } from 'rxjs/operators';

    const source = new Subject<string>();
    const result = source.pipe(isEmpty());
    source.subscribe(x => console.log(x));
    result.subscribe(x => console.log(x));
    source.next('a');
    source.next('b');
    source.next('c');
    source.complete();

    // Salida: a, false, b, c
```

### Recursos adicionales

[![Source code](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/conditional/assets/icons/source-code.png)](https://github.com/ReactiveX/rxjs/blob/master/src/internal/operators/isEmpty.ts)

[Documentación oficial en inglés](https://rxjs.dev/api/operators/isEmpty)


# sequenceEqual

Compara secuencialmente las emisiones de 2 Observables utilizando una función de comparación y retorna un Observable que emite un solo valor booleano indicando si las dos secuencias son o no iguales

<details>

<summary>Signatura</summary>

#### Firma

`sequenceEqual<T>(compareTo: Observable<T>, comparator?: (a: T, b: T) => boolean): OperatorFunction<T, boolean>`

#### Parámetros

#### Retorna

`OperatorFunction<T, boolean>`: Un Observable que emite un solo valor booleano representando si los valores emitidos por ambos Observables son iguales, en el mismo orden.

</details>

## Descripción

Comprueba si todos los valores emitidos por ambos Observables son los mismos, en el mismo orden.

![Diagrama de canicas del operador sequenceEqual](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/conditional/assets/images/marble-diagrams/conditional-boolean/sequenceEqual.md)

`sequenceEqual` se suscribe a dos Observables diferentes y almacena los valores emitidos por cada Observable en un búfer. Cuando cualquiera de los Observables emita un valor, dicho valor se almacena, los búferes se desplazan y se comparan desde abajo hacia arriba; si hay algún par de valores que no sean iguales, el Observable retornado emitirá falso y se completará. Si alguno de los Observables se completa, el operador esperará a que el otro también se complete. Si el otro Observable emite antes de completarse, el Observable retornado emitirá falso y se completará. Si un Observable nunca se completa ni emite después de que el otro se complete, el Observable retornado nunca se completará.

\[REVISAR] subscribes to two observables and buffers incoming values from each observable. Whenever either observable emits a value, the value is buffered and the buffers are shifted and compared from the bottom up; If any value pair doesn't match, the returned observable will emit false and complete. If one of the observables completes, the operator will wait for the other observable to complete; If the other observable emits before completing, the returned observable will emit false and complete. If one observable never completes or emits after the other complets, the returned observable will never complete.

## Ejemplos

Averiguar si la secuencia tecleada se corresponde con el código Konami

```javascript
import { from, fromEvent } from "rxjs";
import { sequenceEqual, bufferCount, mergeMap, map } from "rxjs/operators";

const codes = from([
  "ArrowUp",
  "ArrowUp",
  "ArrowDown",
  "ArrowDown",
  "ArrowLeft",
  "ArrowRight",
  "ArrowLeft",
  "ArrowRight",
  "KeyB",
  "KeyA",
  "Enter", // Obviamente, no tenemos la tecla start
]);

const keys = fromEvent(document, "keyup").pipe(map((e) => e.code));
const matches = keys.pipe(
  bufferCount(11, 1),
  mergeMap((last11) => from(last11).pipe(sequenceEqual(codes)))
);
matches.subscribe((matched) =>
  console.log("Successful cheat at Contra? ", matched)
);
```

### Recursos adicionales

[![Source code](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/conditional/assets/icons/source-code.png)](https://github.com/ReactiveX/rxjs/blob/master/src/internal/operators/sequenceEqual.ts)

[Documentación oficial en inglés](https://rxjs.dev/api/operators/sequenceEqual)


# Creación

* [ajax](/operadores/creation/ajax)
* [defer](/operadores/creation/defer)
* [from](/operadores/creation/from)
* [fromEvent](/operadores/creation/fromevent)
* [fromEventPattern](/operadores/creation/fromeventpattern)
* [fromFetch](/operadores/creation/fromfetch)
* [generate](/operadores/creation/generate)
* [iif](/operadores/creation/iif)
* [interval](/operadores/creation/interval)
* [of](/operadores/creation/of)
* [range](/operadores/creation/range)
* [throwError](/operadores/creation/throwerror)
* [timer](/operadores/creation/timer)


# ajax

Crea un Observable para una petición Ajax

<details>

<summary>Signatura</summary>

#### Firma

`ajax(urlOrRequest: string | AjaxRequest): Observable<AjaxResponse>`

</details>

## Descripción

Crea un Observable para una petición Ajax a partir de un objeto de petición con la url, cabeceras etc. o a partir de una URL.

## Ejemplos

**Realizar una petición Ajax, y emitir el objeto AjaxResponse completo**

[StackBlitz](https://stackblitz.com/edit/docu-rxjs-ajax?file=index.ts)

```javascript
import { ajax } from "rxjs/ajax";

const ghibliFilmsResponse$ = ajax("https://ghibliapi.herokuapp.com/films");

ghibliFilmsResponse$.subscribe(console.log);
// Salida: AjaxResponse { ...request: {...}, status: 200...}
```

**Emitir únicamente los datos del objeto respuesta**

[StackBlitz](https://stackblitz.com/edit/docu-rxjs-ajax-2?file=index.ts)

```javascript
import { ajax } from "rxjs/ajax";
import { mergeAll } from "rxjs/operators";

const ghibliFilm$ = ajax
  .getJSON("https://ghibliapi.herokuapp.com/films")
  .pipe(mergeAll());

ghibliFilm$.subscribe(console.log);
/* Salida:  
{ ...title: 'Castle in the Sky'... },
{ ...title: 'Grave of the Fireflies'... },
{ ...title: 'My Neighbor Totoro'... }...
*/
```

**Utilizar un objeto de configuración para los parámetros de la petición AJAX**

[StackBlitz](https://stackblitz.com/edit/docu-rxjs-ajax-3?file=index.ts)

```javascript
import { ajax } from "rxjs/ajax";

const ghibliFilmWithHeaders$ = ajax({
  url: "https://ghibliapi.herokuapp.com/films",
  method: "GET",
  headers: {
    "Content-Type": "json",
  },
  body: {
    message: "Mensaje personalizado, porque podemos ;)",
  },
});
ghibliFilmWithHeaders$.subscribe(console.log);
// Salida: AjaxResponse {xhr: {}, request: {}...}
```

**Realizar varias peticiones Ajax mediante un operador de proyección de orden superior (**[**mergeMap**](https://github.com/puntotech/rxjs-docu/blob/master/operators/transformation/mergeMap/README.md)**,** [**switchMap**](https://github.com/puntotech/rxjs-docu/blob/master/operators/transformation/switchMap/README.md)**,** [**concatMap**](https://github.com/puntotech/rxjs-docu/blob/master/operators/transformation/concatMap/README.md)**,** [**exhaustMap**](https://github.com/puntotech/rxjs-docu/blob/master/operators/transformation/exhaustMap/README.md)**)**

[StackBlitz](https://stackblitz.com/edit/docu-rxjs-ajax-4?file=index.ts)

```javascript
import { from, of } from "rxjs";
import { ajax } from "rxjs/ajax";
import { catchError, mergeMap } from "rxjs/operators";

const filmId$ = of(
  "58611129-2dbc-4a81-a72f-77ddfc1b1b49",
  "2baf70d1-42bb-4437-b551-e5fed5a87abe"
);

function getGhibliFilm(id: string) {
  return ajax.getJSON(`https://ghibliapi.herokuapp.com/films/${id}`);
}

filmId$.pipe(mergeMap((id) => getGhibliFilm(id))).subscribe(console.log);
// Salida: {...title: 'Castle in the Sky'...}, {...title: 'My Neighbor Totoro'...}
```

### Ejemplos de la documentación oficial

**Usar ajax() para obtener el objeto de respuesta que retorna la API**

```javascript
import { ajax } from "rxjs/ajax";
import { map, catchError } from "rxjs/operators";
import { of } from "rxjs";

const obs$ = ajax(`https://api.github.com/users?per_page=5`).pipe(
  map((userResponse) => console.log("users: ", userResponse)),
  catchError((error) => {
    console.log("error: ", error);
    return of(error);
  })
);
```

**Usar ajax.getJSON() para obtener datos de la API**

```javascript
import { ajax } from "rxjs/ajax";
import { map, catchError } from "rxjs/operators";
import { of } from "rxjs";

const obs$ = ajax.getJSON(`https://api.github.com/users?per_page=5`).pipe(
  map((userResponse) => console.log("users: ", userResponse)),
  catchError((error) => {
    console.log("error: ", error);
    return of(error);
  })
);
```

**Usar ajax() con un objeto como argumento y el método POST con un retraso de 2 segundos**

```javascript
import { ajax } from "rxjs/ajax";
import { of } from "rxjs";

const users = ajax({
  url: "https://httpbin.org/delay/2",
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "rxjs-custom-header": "Rxjs",
  },
  body: {
    rxjs: "Hello World!",
  },
}).pipe(
  map((response) => console.log("response: ", response)),
  catchError((error) => {
    console.log("error: ", error);
    return of(error);
  })
);
```

**Usar ajax() para hacer una llamada a la API, que devuelve un objeto error**

```javascript
import { ajax } from "rxjs/ajax";
import { map, catchError } from "rxjs/operators";
import { of } from "rxjs";

const obs$ = ajax(`https://api.github.com/404`).pipe(
  map((userResponse) => console.log("users: ", userResponse)),
  catchError((error) => {
    console.log("error: ", error);
    return of(error);
  })
);
```

### Recursos adicionales

[![Source code](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/creation/assets/icons/source-code.png)](https://github.com/ReactiveX/rxjs/blob/master/src/internal/ajax/ajax.ts)

[Documentación oficial en inglés](https://rxjs.dev/api/ajax/ajax)


# defer

Crea un Observable que, al ser suscrito, llama a una factoría Observable para crear otro Observable nuevo por cada suscriptor

## Descripción

El Observable se crea de forma diferida, es decir, solamente se crea cuando un Observador se suscribe a él.

![Diagrama de canicas de defer](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/creation/assets/images/marble-diagrams/creation/defer.png)

`defer` nos permite crear Observables únicamente cuando un Observador se suscribe, y crear un Observable nuevo para cada Observador.

Espera a que un Observador se suscriba a él, y entonces genera un Observable nuevo, normalmente mediante una función factoría Observable.

Este proceso se lleva a cabo para cada suscriptor, por lo que, aunque cada suscriptor crea que se está suscribiendo al mismo Observable, en realidad cada suscriptor recibe su propio Observable.

## Ejemplos

**Emitir la fecha/hora en el momento de la suscripción**

[StackBlitz](https://stackblitz.com/edit/docu-rxjs-defer?file=index.ts)

```javascript
import { defer, of } from "rxjs";

const deferredTime$ = defer(() => of(new Date()));

deferredTime$.subscribe(console.log);
// Salida: La fecha en el momento de la suscripción
```

**Crear un Observable que emita una fruta distinta cada vez que un observador se suscribe a él**

[StackBlitz](https://stackblitz.com/edit/docu-rxjs-defer-2?file=index.ts)

```javascript
import { defer, of } from "rxjs";

const fruits = ["Cereza", "Fresa", "Mora", "Arándano"];

function getRandomFruit() {
  return fruits[Math.floor(Math.random() * 3)];
}

// Cada suscriptor a este Observable recibirá SIEMPRE la misma fruta, ya que la función getRandomFruit se ejecuta solo una vez, en el momento en el que se crea el Observable
const randomFruit$ = of(getRandomFruit());

// Cada suscriptor a este Observable recibirá una fruta DISTINTA cada vez, ya que la función getRandomFruit se ejecuta cada vez que nos suscribimos
const randomFruitForReal$ = defer(() => of(getRandomFruit()));

randomFruit$.subscribe(console.log);
// Salida: Cereza
randomFruit$.subscribe(console.log);
// Salida: Cereza

randomFruitForReal$.subscribe(console.log);
// Salida: Fresa
randomFruitForReal$.subscribe(console.log);
// Salida: Mora
```

### Ejemplo de la documentación oficial

**Suscribirse a un Observable de clicks o a un Observable intervalo, de forma aleatoria**

```javascript
import { defer, fromEvent, interval } from "rxjs";

const clicksOrInterval = defer(function () {
  return Math.random() > 0.5 ? fromEvent(document, "click") : interval(1000);
});
clicksOrInterval.subscribe((x) => console.log(x));

// Salida:
// Si el resultado de Math.random() es mayor que 0.5 se suscribirá al Observable de clicks. Si el resultado es menor que 0.5 se suscribirá al Observable intervalo
```

### Recursos adicionales

[![Source code](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/creation/assets/icons/source-code.png)](https://github.com/ReactiveX/rxjs/blob/master/src/internal/observable/defer.ts)

[Documentación oficial en inglés](https://rxjs.dev/api/index/function/defer)


# from

Crea un Observable a partir de un Array, un objeto similar a un Array, una Promesa, un objeto iterable o un objeto similar a un Observable

<details>

<summary>Signatura</summary>

#### Firma

`from<T>(input: any, scheduler?: SchedulerLike): Observable<T>`

#### Parámetros

#### Retorna

`Observable<T>`: Un Observable que emite los argumentos descritos anteriormente y se completa.

</details>

## Descripción

Convierte prácticamente cualquier elemento en un Observable.

![Diagrama de canicas de from](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/creation/assets/images/marble-diagrams/creation/from.png)

`from` convierte varios tipos de datos u objetos en Observables. También puede convertir una Promesa, un objeto similar a un Array o un objeto iterable en un Observable que emite los elementos de dicha Promesa, Array o iterable. Un String, en este contexto, se interpreta como un array de caracteres. Los objetos similares a Observables (contienen una función nombrada con el Símbolo ES2015 que corresponde a Observable) también se puede transformar mediante este operador.

## Ejemplos

**Crear un Observable a partir de una cadena**

[StackBlitz](https://stackblitz.com/edit/docu-rxjs-from?file=index.ts)

```javascript
import { from } from "rxjs";

const letter$ = from("RxJS mola");

letter$.subscribe(console.log);
// Salida: 'R', 'x', 'J', 'S', ' ', 'm', 'o', 'l', 'a'
```

**Crear un Observable a partir de un Array de cadenas**

[StackBlitz](https://stackblitz.com/edit/docu-rxjs-from-2?file=index.ts)

```javascript
import { from } from "rxjs";

const fruit$ = from(["Fresa", "Cereza", "Mora"]);

fruit$.subscribe((fruit) => console.log(fruit));
// Salida: Fresa, Cereza, Mora
```

**Crear un Observable a partir de un Map**

[StackBlitz](https://stackblitz.com/edit/docu-rxjs-from-3?file=index.ts)

```javascript
import { from } from "rxjs";

const language$ = from(
  new Map([
    ["Java", "Orientado a objetos"],
    ["Ruby", "Multiparadigma"],
    ["Haskell", "Funcional"],
  ])
);

language$.subscribe(console.log);
// Salida: ["Java", "Orientado a objetos"], ["Ruby", "Multiparadigma"], ["Haskell", "Funcional"]
```

**Crear un Observable a partir de una promesa**

[StackBlitz](https://stackblitz.com/edit/docu-rxjs-from-4?file=index.ts)

```javascript
import { from } from "rxjs";

const promise$ = from(Promise.resolve("Prometo empezar a aprender RxJS"));

promise$.subscribe(console.log);
// Salida: 'Prometo empezar a aprender RxJS'
```

**Crear un Observable a partir de un NodeList**

[StackBlitz](https://stackblitz.com/edit/docu-rxjs-from-5?file=index.ts)

```javascript
import { from } from "rxjs";

const node$ = from(document.querySelectorAll("p"));

node$.subscribe((node) => console.log(node));
// Salida: HTMLParagraphElement {tagName: "p", attributes: {...}}
```

### Ejemplos de la documentación oficial

**Convertir un array a un Observable**

```javascript
import { from } from "rxjs";

const array = [10, 20, 30];
const result = from(array);

result.subscribe((x) => console.log(x));

// Salida:
// 10
// 20
// 30
```

**Convertir un iterable infinito (a partir de un generador) en un Observable**

```javascript
import { from } from "rxjs";
import { take } from "rxjs/operators";

function* generateDoubles(seed) {
  let i = seed;
  while (true) {
    yield i;
    i = 2 * i; // dóblalo
  }
}

const iterator = generateDoubles(3);
const result = from(iterator).pipe(take(10));

result.subscribe((x) => console.log(x));

// Salida:
// 3
// 6
// 12
// 24
// 48
// 96
// 192
// 384
// 768
// 1536
```

**Con el planificador asyncScheduler**

```javascript
import { from, asyncScheduler } from "rxjs";

console.log("Comienzo");

const array = [10, 20, 30];
const result = from(array, asyncScheduler);

result.subscribe((x) => console.log(x));

console.log("Fin");

// Salida:
// Comienzo
// Fin
// 10
// 20
// 30
```

### Recursos adicionales

[![Source code](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/creation/assets/icons/source-code.png)](https://github.com/ReactiveX/rxjs/blob/master/src/internal/observable/from.ts)

[Documentación oficial en inglés](https://rxjs.dev/api/index/function/from)


# fromEvent

Crea un Observable que emite eventos de un tipo específico, originados en el event target proporcionado

<details>

<summary>Signatura</summary>

#### Firma

`fromEvent<T>(target: FromEventTarget<T>, eventName: string, options?: EventListenerOptions | ((...args: any[]) => T), resultSelector?: (...args: any[]) => T): Observable<T>`

#### Parámetros

#### Retorna

`Observable<T>`:

</details>

## Descripción

Crea un Observable a partir de eventos del DOM, de eventos EventEmitter de Node.js u otros.

![Diagrama de canicas del operador fromEvent](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/creation/assets/images/marble-diagrams/creation/fromEvent.png)

`fromEvent` acepta un *event target* como primer argumento. Un *event target* es un objeto con métodos para registrar las funciones de manejo de eventos. Como segundo argumento recibe una cadena que indica el tipo de evento al que se quiere escuchar. `fromEvent` es compatible con varios tipos de *event targets*, listados un poco más abajo. Si se desea utilizar *event target* que no sea compatible con `fromEvent`, se debe utilizar `fromEventPattern`, que da soporte a APIs arbitrarias. En el caso de las APIs compatibles con `fromEvent`, los métodos para añadir y elminar funciones de manejo de eventos se llaman de diferente manera, pero todos aceptan una cadena que describe el tipo de evento y la función en sí, que puede llamarse cuando dicho evento se dispare.

Cada vez que se realiza una suscripción al Observable resultante, la función de manejo de eventos se registra al `event target`. Cuando el evento se dispare, el valor que se pase como primer argumento a la función registrada será emitido por el Observable resultante. Cuando se cancele la suscripción al Observable, la función se desvinculará del *event target*.

Se debe tener en cuenta que si las llamadas a la función registrada al *event target* se hacen con más de un argumento, ningún argumento a partir del segundo, este inclusive, aparecerá en el flujo resultante. Para poder acceder a dichos argumentos, se le puede proporcionar una función de proyección opcional a `fromEvent`, que se llamará con todos los argumentos proporcionados al manejador de eventos. El Observable resultante emitirá los valores retornados por la función de proyección, en lugar del valor habitual.

También debe tenerse en cuenta que los *event targets* listados más adelante se comprueban mediante [duck typing](https://es.wikipedia.org/wiki/Duck_typing), o tipifación dinámica. Esto implica que, independientemente del tipo de objeto y del entorno en el que se trabaje, se puede utilizar `fromEvent` en dicho objeto si se exponen los métodos descritos (siempre y cuando se tengan el comportamiento descrito anteriormente). Por ejemplo, si una biblioteca de Node.js expone un *event target* cuyos métodos se llaman igual que los del `EventTarget` del DOM, el utilizar `fromEvent` es una buena elección.

Si la API que se desea utilizar es más orientada a *callback* que a *event handler* (la función *callback* suscrita se dispara únicamente una vez, por lo que no hay necesidad de desvincularla manualmente), se debe utilizar `bindCallback` o `bindNodeCallback` en lugar de `fromEvent`.

`fromEvent` es compatible con los siguientes tipos de *event targets*:

### DOM EventTarget

Es un objeto con los métodos `addEventListener` y `removeEventListener`.

En el navegador, `addEventListener` recibe, además de la cadena indicando el tipo de evento y la función de manejo de eventos, un tercer parámetro opcional, que es o bien un objeto o un booleano, ambos utilizados para agregar configuración adicional de cuándo y cómo se hará la llamada a la función proporcionada.

### Node.js EventEmitter

Es un objeto con los métodos `addListener` y `removeListener`.

### JQuery-style event target

Es un objeto con los métodos `on` y `off`.

### DOM NodeList

Es una lista de Nodos del DOM, como por ejemplo, la que retornan `document.querySelectorAll` o `Node.childNodes`.

Aunque esta colección no es un *event target* propiamente dicho, `fromEvent` iterará a través de todos los Nodos que contenta e instalará la función de manejo de eventos en cada uno de ellos. Cuando se cancele la suscripción al Observable retornado, la función será retirada de todos los Nodos.

### DOM HtmlCollection

Al igual que en el caso de un `NodeList`, se trata de una colección de Nodos del DOM. En este caso, la función de manejo de eventos se vinculará y desvinculará de cada uno de los elementos.,

## Ejemplos

**Crear un Observable que emite clicks**

[StackBlitz](https://stackblitz.com/edit/docu-rxjs-fromevent?file=index.ts)

```typescript
import { fromEvent } from "rxjs";

const click$ = fromEvent<MouseEvent>(document, "click");

click$.subscribe((click) => console.log(click));
// Salida: (click) MouseEvent {isTrusted: true}
```

**Crear un Observable que emite teclas pulsadas**

[StackBlitz](https://stackblitz.com/edit/docu-rxjs-fromevent-2?file=index.ts)

```typescript
import { fromEvent } from "rxjs";

const keyPressed$ = fromEvent<KeyboardEvent>(document, "keydown");

keyPressed$.subscribe(console.log);
// Salida: (pulsar tecla) KeyboardEvent {isTrusted: true}
```

**Crear un Observable que emita cambios en el scroll**

[StackBlitz](https://stackblitz.com/edit/docu-rxjs-fromevent-3?file=index.ts)

```typescript
import { fromEvent } from "rxjs";

const scroll$ = fromEvent<UIEvent>(document, "scroll");

scroll$.subscribe((scroll) => console.log(scroll));
// Salida: (scroll) UIEvent {isTrusted: true}
```

**Crear un Observable que emite cuando se copie un texto**

[StackBlitz](https://stackblitz.com/edit/docu-rxjs-fromevent-4?file=index.ts)

```typescript
import { fromEvent } from "rxjs";

const copie$ = fromEvent<ClipboardEvent>(document, "copy");

copie$.subscribe(console.log);
// Salida: (copiar) ClipboardEvent {isTrusted: true}
```

### Ejemplos de la documentación oficial

**Emitir los clicks que ocurran en el DOM**

```javascript
import { fromEvent } from "rxjs";

const clicks = fromEvent(document, "click");
clicks.subscribe((x) => console.log(x));

// Salida:
// (click) MouseEvent{...} (click) MouseEvent{...}
```

**Usar addEventListener con la opción de captura**

```javascript
import { fromEvent } from "rxjs";

const clicksInDocument = fromEvent(document, "click", true); // Nótese el parámetro de configuración opcionalparameter
// que se le pasará a addEventListener
const clicksInDiv = fromEvent(someDivInDocument, "click");

clicksInDocument.subscribe(() => console.log("document"));
clicksInDiv.subscribe(() => console.log("div"));

// Por defecto, los eventos se propagan hacia arriba por el árbol del DOM,
// por lo que, normalmente, cuando se hace click en el div
// primero se mostrará "div" primero en la consola, y después "document".
// Dado que se ha especificado la opción `capture` option, el "document"
// capturará el evento cuando se propague hacia ABAJO en el árbol del DOM, por lo
// que la consola mostrará "document" primero, y luego "div".
```

### Recursos adicionales

[![Source code](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/creation/assets/icons/source-code.png)](https://github.com/ReactiveX/rxjs/blob/master/src/internal/observable/fromEvent.ts)

[Documentación oficial en inglés](https://rxjs.dev/api/index/function/fromEvent)


# fromEventPattern

Crea un Observable a partir de una API arbitraria de registro de manejadores de eventos

<details>

<summary>Signatura</summary>

#### Firma

`fromEventPattern<T>(addHandler: (handler: NodeEventHandler) => any, removeHandler?: (handler: NodeEventHandler, signal?: any) => void, resultSelector?: (...args: any[]) => T): Observable<T | T[]>`

#### Parámetros

#### Retorna

`Observable<T | T[]>`: Un Observable que, cuando se dispara un evento, emite o el primer parámetro que se le haya proporcionado al manejador de eventos registrado, o el resultado de la función de proyección.

</details>

## Descripción

Se utiliza cuando `fromEvent` no está preparado para manejar un determinado método para añadir manejadores de eventos.

![Diagrama de canicas de fromEventPattern](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/creation/assets/images/marble-diagrams/creation/fromEventPattern.png)

`fromEventPattern` permite convertir cualquier API de registro de funciones manejadores en eventos, en un Observable. Es similar a `fromEvent`, pero mucho más flexible. De hecho, todos los casos de uso de `fromEvent` podrían manejarse con `fromEventPattern` (aunque de forma más verbosa.)

Este operador recibe una función `addHandler` como primer argumento, que se inyecta con un parámetro `handler`. Dicho `handler` es una función de manejo de eventos que se le puede proporcionar a la API que la espera. `addHandler` se llamará cuando se realice alguna suscripción al Observable retornado por `fromEventPattern`, por lo que el registro del manejador en la API no tiene que ocurrir necesariamente cuando se llame a `fromEventPattern`.

Tras el registro, cada vez que se dispare un evento al que se está escuchando, el Observable retornado por `fromEventPattern` emitirá el valor con el que se haya llamado a la función de manejo de eventos. Si el manejador de eventos se ha llamado con más de un argumento, ningún argumento a partir del segundo, este inclusive, aparecerá en el flujo resultante.

Si la API utilizada permite desvincular manejadores de eventos, se le puede pasar un segundo parámetro a `fromEventPattern`: la función `removeHandler`. Se inyectará con la misma función manejadora que antes, pero ahora se puede utilizar para desvincularla de la API. `removeHandler` será llamada cuando el consumidor del Observable resultante cancele la suscripción a dicho Observable.

En algunas APIs, la desvinculación del manejador de eventos se maneja de otra forma. Al vincular un manejador de eventos, se retorna algún tipo de token, que o bien se utiliza después para identificar qué función se debe desvincular, o el propio token contiene un método para desvincular el manejador de eventos. Si ese es el caso, se debe asegurar que el token retornado por el método de registro lo retorna la función `addHandler`. Entonces se le proporcionará a `removeHandler` como segundo argumento, donde se podrá hacer uso de él.

Si se necesita tener acceso a todos los parámetros del manejador de eventos, o se necesita poder transformarlos, se le puede proporcionar un tercer parámetro opcional a `fromEventPattern`: una función de proyección que acepta todos los argumentos pasados al manejador de eventos. El resultado de la función de proyección aparecerá en el flujo resultante en lugar del primer argumento del manejador de eventos.

## Ejemplos

### Ejemplos de la documentación oficial

Emitir los clicks que ocurran en el DOM

```javascript
import { fromEventPattern } from "rxjs";

function addClickHandler(handler) {
  document.addEventListener("click", handler);
}

function removeClickHandler(handler) {
  document.removeEventListener("click", handler);
}

const clicks = fromEventPattern(addClickHandler, removeClickHandler);
clicks.subscribe((x) => console.log(x));
// (click) MouseEvent {} (click) MouseEvent {}
```

Usar `fromEventPattern` con una API que retorna un token de cancelación

```javascript
import { fromEventPattern } from "rxjs";

const token = someAPI.registerEventHandler(function () {});
someAPI.unregisterEventHandler(token); // El método de cancelación de esta API recibe un token especial en lugar de un manejador

const someAPIObservable = fromEventPattern(
  function (handler) {
    return someAPI.registerEventHandler(handler);
  }, // Aquí se retorna el token...
  function (handler, token) {
    someAPI.unregisterEventHandler(token);
  } // ...para utilizarlo aquí
);
```

Usar `fromEventPattern` con función de proyección

```javascript
    import { fromEventPattern } from 'rxjs';

    someAPI.registerEventHandler((eventType, eventMessage) => {
      console.log(eventType, eventMessage); // Imprime "EVENT_TYPE" "EVENT_MESSAGE" por consola
    });

    const someAPIObservable = fromEventPattern(
      handler => someAPI.registerEventHandler(handler),
      handler => someAPI.unregisterEventHandler(handler)
      (eventType, eventMessage) => eventType + " --- " + eventMessage // Sin esta función solo se emitiría "EVENT_TYPE"
    );

    someAPIObservable.subscribe(value => console.log(value));

    // Salida:
    // "EVENT_TYPE --- EVENT_MESSAGE"
```

### Recursos adicionales

[![Source code](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/creation/assets/icons/source-code.png)](https://github.com/ReactiveX/rxjs/blob/master/src/internal/observable/fromEventPattern.ts)

[Documentación oficial en inglés](https://rxjs.dev/api/index/function/fromEventPattern)


# fromFetch

Utiliza la API Fetch para hacer una petición HTTP

<details>

<summary>Signatura</summary>

#### Firma

`fromFetch<T>(input: string | Request, initWithSelector: RequestInit & { selector?: (response: Response) => any; } = {}): Observable<Response | T>`

#### Parámetros

#### Retorna

`Observable<Response | T>`: Un Observable que hace una petición HTTP usando la función `fetch` nativa, cuando un Observador se suscribe a él. La Suscripción está atada al `AbortController` para el `fetch`.

</details>

## Descripción

ADVERTENCIA: Partes de la API de `fetch` siguen siendo experimentales. `AbortController` es imprescindible para que esta implementación funcione y para llevar a cabo la cancelación apropiadamente.

`fromFetch` automáticamente genera un `AbortController` interno para eliminar el `fetch` interno cuando se cancele la suscripción.

Si se proporciona una señal vía el argumento `init`, esta se comportará igual que con `fetch`. Si la señal proporcionada aborta, el error que `fetch` normalmente lanza se emitirá como un error del Observable.

## Ejemplos

**Realizar una petición `fetch` y emitir el objeto `Response` al completo**

[StackBlitz](https://stackblitz.com/edit/docu-rxjs-fromfetch?file=index.ts)

```javascript
import { fromFetch } from "rxjs/fetch";

const ghibliFilmResponse$ = fromFetch("https://ghibliapi.herokuapp.com/films");

ghibliFilmResponse$.subscribe(console.log);
// Salida: Response {...}
```

### Ejemplos de la documentación oficial

```javascript
import { of } from "rxjs";
import { fromFetch } from "rxjs/fetch";
import { switchMap, catchError } from "rxjs/operators";

const data$ = fromFetch("https://api.github.com/users?per_page=5").pipe(
  switchMap((response) => {
    if (response.ok) {
      // OK devolver los datos
      return response.json();
    } else {
      // El servidor retorna un status requiriendo que el cliente intente otra cosa
      return of({ error: true, message: `Error ${response.status}` });
    }
  }),
  catchError((err) => {
    // Gestionando cualquier tipo de error
    console.error(err);
    return of({ error: true, message: err.message });
  })
);

data$.subscribe({
  next: (result) => console.log(result),
  complete: () => console.log("done"),
});
```

## Uso con codificación de transferencia fragmentada

Con las respuestas HTTP que utilicen codificación de transferencia fragmentada, la promesa retornada por fetch se resolverá en cuanto se reciban las cabeceras de la respuesta.

Esto implica que el Observable fromFetch emitirá una respuesta - y se completará - antes de recibir el cuerpo de la petición. Cuando uno de los métodos de la respuesta - como text() o json() - sea llamado, la promesa retornada no se resolverá hasta que el cuerpo completo se haya recibido. Cancelar la suscripción a cualquier Observable que use la promesa como entrada no abortará la petición.

Para facilitar el aborto de la recuperación de respuestas que utilicen codificación de transferencia fragmentada, se puede especificar un selector vía el parámetro init:

```javascript
import { of } from "rxjs";
import { fromFetch } from "rxjs/fetch";

const data$ = fromFetch("https://api.github.com/users?per_page=5", {
  selector: (response) => response.json(),
});

data$.subscribe({
  next: (result) => console.log(result),
  complete: () => console.log("done"),
});
```

### Recursos adicionales

[![Source code](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/creation/assets/icons/source-code.png)](https://github.com/ReactiveX/rxjs/blob/master/src/internal/observable/dom/fetch.ts)

[Documentación oficial en inglés](https://rxjs.dev/api/fetch/fromFetch)


# generate

Genera un Observable ejecutando un bucle impulsado por el estado que emite un elemento en cada iteración

<details>

<summary>Signatura</summary>

#### Firma

`generate(initialState: S, condition: ConditionFunc<S>, iterate: IterateFunc<S>, scheduler?: SchedulerLike): Observable<S>`

#### Parámetros

#### Retorna

`Observable<S>`: La secuencia generada.

</details>

## Descripción

Se utiliza en lugar de hacer llamadas a `next` dentro de un bucle for.

![Diagrama de canicas de generate](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/creation/assets/images/marble-diagrams/creation/generate.png)

generate permite crear un flujo de valores generador con un bucle muy similar a un bucle for tradicional.

* El primer argumento de generate es el valor inicial.
* El segundo valor es una función que acepta este valor y comprueba si una condición se sigue o no cumpliendo. En caso afirmativo, el bucle continúa. Si no, el bucle se para.
* El tercer valor es una función que recibe el valor definido anteriormente y lo modifica en cada iteración.

Estos tres parámetros son equivalentes a las tres expresiones de un bucle for tradicional: la primera expresión inicializa un estado (como por ejemplo un índice numérico), la segunda comprueba si el bucle puede o no hacer la siguiente iteración (como por ejemplo si el índice es menor que 10) y la tercera indica cómo el valor definido se modifica en cada iteración (como por ejemplo, incrementar dicho valor en 1.)

El vaor retornado del operador generate es un Observable que emite un valor en cada iteración del bucle. Primero, se ejecuta la función de condición. Si la función retorna *true*, el Observable emite el valor almacenado (el valor inicial en la primera iteración) y después actualiza dicho valor con la función de iteración. Si en algún momento la función de condición retorna *false*, el Observable se completa.

Opcionalmente, se le puede proporcionar un cuarto parámetro a generate - una función de selección de resultado.

Si se encuentra que las tres funciones anónimas en la llamada a generate son difíciles de leer, se le puede proporcionar un solo objeto en su lugar. Dicho objeto tiene las siguientes propiedades:

* initialState
* condition
* iterate
* resultSelector

La propiedad condition es opcional en este objeto. Si se omite dicha propiedad, la condición siempre se cumplirá, por lo que el Observable de salida nunca llegará a completarse. El valor de la propiedad resultSelector sigue siendo opcional.

Ambas formas de generate reciben un planificador de forma opcional. En el caso de la llamada multiparámetro, el planificador se proporciona como último argumento (independientemente de que haya una función resultSelector o no.) En el caso de la llamada monoparámetro, se puede proporcionar como propiedad *scheduler* en el objeto proporcionado al operador. En ambos casos el planificador decide el momento en el que ocurre la siguiente iteración del bucle, y por tanto, cuándo se emite la siguiente notificación next. Por ejemplo, para asegurar que cada valor se emite en una tarea distinta del bucle de eventos, se puede utilizar el Planificador async. Por defecto los valores se emiten de forma síncrona.

## Ejemplos

**Emitir los números del 1 al 10**

[StackBlitz](https://stackblitz.com/edit/docu-rxjs-generate?file=index.ts)

```javascript
import { generate } from "rxjs";

const number$ = generate(
  1,
  (x) => x < 10,
  (x) => x + 1
);

number$.subscribe(console.log);
// Salida: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
```

**Emitir los números pares del 2 al 10, utilizando un objeto como parámetro**

[StackBlitz](https://stackblitz.com/edit/docu-rxjs-generate-2?file=index.ts)

```javascript
import { generate } from "rxjs";

const evenNumber$ = generate({
  initialState: 2,
  condition: (x) => x <= 10,
  iterate: (x) => x + 2,
});

evenNumber$.subscribe((number) => console.log(number));
// Salida: 2, 4, 6, 8, 10
```

<details>

<summary>Sobrecargas</summary>

#### Firma

`generate<T, S>(initialStateOrOptions: S | GenerateOptions<T, S>, condition?: ConditionFunc<S>, iterate?: IterateFunc<S>, resultSelectorOrObservable?: SchedulerLike | ResultFunc<S, T>, scheduler?: SchedulerLike): Observable<T>`

#### Parámetros

#### Retorna

`Observable<T>`

#### Firma

`generate(initialState: S, condition: ConditionFunc<S>, iterate: IterateFunc<S>, resultSelector: ResultFunc<S, T>, scheduler?: SchedulerLike): Observable<T>`

Genera una secuencia observable ejecutando un bucle impulsado por el estado para producir los elementos de la secuencia, utilizando el planificador especificado para enviar los mensajes.

#### Parámetros

#### Retorna

`Observable<T>`: La secuencia generada.

#### Firma

`generate(options: GenerateBaseOptions<S>): Observable<S>`

Genera una secuencia observable ejecutando un bucle impulsado por el estado para producir los elementos de la secuencia, utilizando el planificador especificado para enviar los mensajes. Esta sobrecarga acepta un objeto `options` que puede contener `initialState`, `iterate`, `condition` y `scheduler`.

#### Parámetros

#### Retorna

`Observable<S>`: La secuencia generada.

#### Firma

`generate(options: GenerateOptions<T, S>): Observable<T>`

Genera una secuencia observable ejecutando un bucle impulsado por el estado para producir los elementos de la secuencia, utilizando el planificador especificado para enviar los mensajes. Esta sobrecarga acepta un objeto `options` que puede contener `initialState`, `iterate`, `condition`, `resultSelector` y `scheduler`.

#### Parámetros

#### Retorna

`Observable<T>`: La secuencia generada.

</details>

### Recursos adicionales

[![Source code](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/creation/assets/icons/source-code.png)](https://github.com/ReactiveX/rxjs/blob/master/src/internal/observable/generate.ts)

[Documentación oficial en inglés](https://rxjs.dev/api/index/function/generate)


# iif

Decide qué Observable será suscrito en tiempo de suscripción

<details>

<summary>Signatura</summary>

#### Firma

`iif<T = never, F = never>(condition: () => boolean, trueResult: SubscribableOrPromise<T> = EMPTY, falseResult: SubscribableOrPromise<F> = EMPTY): Observable<T | F>`

#### Parámetros

Condition which Observable should be chosen.

#### Retorna

`Observable<T | F>`: Según la condición, devuelve el primer o el segundo Observable.

</details>

## Descripción

Es una sentencia if para Observables.

`iif` acepta una función `condition` y dos Observables. Cuando se realiza la suscripción a un Observable retornado por el operador, se llama a la función `condition`. Según el valor booleano que devuelva la función, el consumidor se suscribirá al primer Observable (si la condición es cierta) o al segundo Observable (si la condición es falsa.) Es posible que la función `condition` no retorna nada - en cuyo caso la condición será evaluada como falsa y se realizará la suscripción al segundo Observable.

Los Observables para ambos casos (*true* y *false*) son opcionales. Si la condición indica la suscripción a un Observable que sea `undefined`, el flujo resultante se completará inmediatamente. Esto permite que, en lugar de controlar a qué Observable se realizará la suscripción, se decida en tiempo de ejecución si un Observable tiene o no acceso a un determinado Observable.

En el caso de tener lógica más compleja que requiera decidir entre más de dos Observables, el operador `defer` probablemente sea una opción mejor. De hecho, el comportamiento del operador `iif` se puede implementar fácilmente con el operador `defer`, y existe únicamente por razones de conveniencia y legibilidad.

## Ejemplos

## Ejemplos de la documentación oficial

**Cambia en tiempo de ejecución qué Observable será suscrito**

```javascript
import { iif, of } from "rxjs";

let subscribeToFirst;
const firstOrSecond = iif(() => subscribeToFirst, of("first"), of("second"));

subscribeToFirst = true;
firstOrSecond.subscribe((value) => console.log(value));

// Logs:
// "first"

subscribeToFirst = false;
firstOrSecond.subscribe((value) => console.log(value));

// Logs:
// "second"
```

**Controlar el acceso a un Observable**

```javascript
let accessGranted;
const observableIfYouHaveAccess = iif(
  () => accessGranted,
  of("It seems you have an access...") // Note that only one Observable is passed to the operator.
);

accessGranted = true;
observableIfYouHaveAccess.subscribe(
  (value) => console.log(value),
  (err) => {},
  () => console.log("The end")
);

// Logs:
// "It seems you have an access..."
// "The end"

accessGranted = false;
observableIfYouHaveAccess.subscribe(
  (value) => console.log(value),
  (err) => {},
  () => console.log("The end")
);

// Logs:
// "The end"
```

### Recursos adicionales

[![Source code](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/creation/assets/icons/source-code.png)](https://github.com/ReactiveX/rxjs/blob/master/src/internal/observable/iif.ts)

[Documentación oficial en inglés](https://rxjs.dev/api/index/function/iif)


# interval

Crea un Observable que emite una secuencia de números, con el intervalo de tiempo entre emisiones que se especifique

<details>

<summary>Signatura</summary>

#### Firma

`interval(period: number = 0, scheduler: SchedulerLike = async): Observable<number>`

#### Parámetros

#### Retorna

`Observable<number>`: Un Observable que emite una secuencia incremental de números, emitiendo un valor en cada intervalo de tiempo.

</details>

## Descripción

Emite una secuencia incremental de números periódicamente.

![Diagrama de canicas de interval](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/creation/assets/images/marble-diagrams/creation/interval.png)

`interval` retorna un Observable que emite una secuencia incremental infinita de números, con un intervalo de tiempo constante entre cada emisión. La primera emisión no se envía inmediatamente, sino al terminar el primer periodo de tiempo. Por defecto, este operador utiliza el `SchedulerLike` async para proporcionar una noción del tiempo, pero se le puede pasar cualquier otro `SchedulerLike` por parámetros.

## Ejemplos

**Emitir una secuencia de números ascendente con un intervalo de 2 segundos entre cada emisión**

[StackBlitz](https://stackblitz.com/edit/docu-rxjs-interval?file=index.ts)

```javascript
import { interval } from "rxjs";

const number$ = interval(2000);

number$.subscribe(console.log);
// Salida: 0, 1, 2, 3, 4, 5...
```

**Si no se le proporciona ningún valor a interval, emitirá valores cada 0ms**

[StackBlitz](https://stackblitz.com/edit/docu-rxjs-interval-2?file=index.ts)

```javascript
import { interval } from "rxjs";

const superFastNumber$ = interval();

superFastNumber$.subscribe((number) => console.log(number));
// Salida: O, 1, 2, 3, 4, 5, 6, 7, 8, 9...
```

### Ejemplo de la documentación oficial

**Emite números ascendentes, uno cada segundo (1000ms) hasta el número 3**

```javascript
import { interval } from "rxjs";
import { take } from "rxjs/operators";

const numbers = interval(1000);

const takeFourNumbers = numbers.pipe(take(4));

takeFourNumbers.subscribe((x) => console.log("Next: ", x));
// Salida: "Next: 0", "Next: 1", "Next: 2", "Next: 3"
```

### Recursos adicionales

[![Source code](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/creation/assets/icons/source-code.png)](https://github.com/ReactiveX/rxjs/blob/master/src/internal/observable/interval.ts)

[Documentación oficial en inglés](https://rxjs.dev/api/index/function/interval)


# of

Convierte los argumentos en una secuencia Observable

<details>

<summary>Signatura</summary>

#### Firma

`of(...args: (SchedulerLike | T)[]): Observable`

#### Parámetros

#### Retorna

`Observable<T>`: Un Observable que emite los argumentos descritos anteriormente y se completa.

</details>

## Descripción

Cada argumento se convierte en una notificación next.

![Diagrama de canicas de of](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/creation/assets/images/marble-diagrams/creation/of.png)

Al contrario que [from](https://github.com/puntotech/rxjs-docu/blob/master/operators/creation/from/README.md), no se lleva a cabo ninguna aplanación y cada argumento al completo se emite como una notificación `next`.

## Ejemplos

**Emitir una secuencia de números**

[StackBlitz](https://stackblitz.com/edit/docu-rxjs-of?file=index.ts)

```javascript
import { of } from "rxjs";

const number$ = of(1, 2, 3, 4, 5);

number$.subscribe((number) => console.log(number));
// Salida: 1, 2, 3, 4, 5
```

**Emitir una secuencia de cadenas**

[StackBlitz](https://stackblitz.com/edit/docu-rxjs-of-2?file=index.ts)

```javascript
import { of } from "rxjs";

const framework$ = of("Angular", "React", "Vue");

framework$.subscribe(console.log);
// Salida: Angular, React, Vue
```

**Emitir una secuencia de arrays**

[StackBlitz](https://stackblitz.com/edit/docu-rxjs-of-3?file=index.ts)

```javascript
import { of } from "rxjs";

const fruit$ = of(["Fresa", "Cereza"], ["Limón", "Naranja"]);

fruit$.subscribe((fruit) => console.log(fruit));
// Salida: ["Fresa", "Cereza"] ["Limón", "Naranja"]
```

**Emitir una secuencia de objetos**

[StackBlitz](https://stackblitz.com/edit/docu-rxjs-of-4?file=index.ts)

```javascript
import { of } from "rxjs";

const iceCream$ = of(
  { size: "Grande", toppings: ["Galletas Oreo", "Sirope de Chocolate"] },
  { size: "Pequeño", toppings: ["Fresas"] }
);

iceCream$.subscribe(console.log);
// Salida: { size: "Grande", toppings: ["Galletas Oreo", "Sirope de Chocolate"] } { size: "Pequeño", toppings: ["Fresas"] }
```

### Ejemplos de la documentación oficial

**Emitir los valores 10, 20, 30**

```javascript
import { of } from "rxjs";

of(10, 20, 30).subscribe(
  (next) => console.log("next:", next),
  (err) => console.log("error:", err),
  () => console.log("Fin")
);
// Salida:
// 'next: 10'
// 'next: 20'
// 'next: 30'
// 'Fin'
```

**Emitir el array \[1,2,3]**

```javascript
import { of } from "rxjs";

of([1, 2, 3]).subscribe(
  (next) => console.log("next:", next),
  (err) => console.log("error:", err),
  () => console.log("Fin")
);
// Salida:
// 'next: [1,2,3]'
// 'Fin'
```

### Recursos adicionales

[![Source code](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/creation/assets/icons/source-code.png)](https://github.com/ReactiveX/rxjs/blob/master/src/internal/observable/of.ts)

[Documentación oficial en inglés](https://rxjs.dev/api/index/function/of)


# range

Crea un Observable que emite una secuencia de números dentro de un rango

<details>

<summary>Signatura</summary>

#### Firma

`range(start: number = 0, count?: number, scheduler?: SchedulerLike): Observable<number>`

#### Parámetros

#### Retorna

`Observable<number>`: Un Observable de números que emite una secuencia finita de números consecutivos dentro de un rango.

</details>

## Descripción

Emite una secuencia de números dentro de un rango.

![Diagrama de canicas de range](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/creation/assets/images/marble-diagrams/creation/range.png)

`range` emite una secuencia de números en un rango, en orden, donde se permite seleccionar el comienzo del rango y su longitud. Por defecto, no se utiliza ningún `SchedulerLike`, por lo que las notificaciones se emiten de forma síncrona, pero se puede proporcionar un `SchedulerLike` opcional para regular dichas notificaciones.

## Ejemplos

**Emitir una secuencia de 5 números. Al no especificar el comienzo del rango, se utilizará el valor por defecto: 0**

[StackBlitz](https://stackblitz.com/edit/docu-rxjs-range?file=index.ts)

```javascript
import { range } from "rxjs";

const number$ = range(5);

number$.subscribe((number) => console.log(number));
// Salida: 0, 1, 2, 3, 4
```

**Emitir una secuencia de 5 números, especificando el valor inicial**

[StackBlitz](https://stackblitz.com/edit/docu-rxjs-ramge-2?file=index.ts)

```javascript
import { range } from "rxjs";

const range$ = range(1, 5);

range$.subscribe(console.log);
// Salida: 1, 2, 3, 4, 5
```

### Ejemplo de la documentación oficial

**Emitir los números del 1 al 10**

```javascript
import { range } from "rxjs";

const numbers = range(1, 10);
numbers.subscribe((x) => console.log(x));
```

### Recursos adicionales

[![Source code](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/creation/assets/icons/source-code.png)](https://github.com/ReactiveX/rxjs/blob/master/src/internal/observable/range.ts)

[Documentación oficial en inglés](https://rxjs.dev/api/index/function/range)


# throwError

Crea un Observable que solo emite una notificación de error

<details>

<summary>Signatura</summary>

#### Firma

`throwError(error: any, scheduler?: SchedulerLike): Observable<never>`

#### Parámetros

#### Retorna

`Observable<never>`: Un Observable de error: emite solo la notificación `error` utilizando el argumento `error` proporcionado

</details>

## Descripción

Emite un Error y nada más.

![Diagrama de canicas de throw](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/creation/assets/images/marble-diagrams/creation/throwError.png)

Este operador estático es útil para crear un Observable simple que solo emite la notificación de error. Se puede utilizar para la composición de Observables, como por ejemplo, usando `mergeMap`.

## Ejemplos

**Emitir un error simple**

[StackBlitz](https://stackblitz.com/edit/docu-rxjs-throwerror?file=index.ts)

```javascript
import { throwError } from "rxjs";

const error$ = throwError("¡Oh no!");

error$.subscribe(
  (result) => console.log(result),
  (error) => console.error(error)
);
// Salida: (error) 'Oh no!
```

**Lanzar un error según se cumpla una condición**

[StackBlitz](https://stackblitz.com/edit/docu-rxjs-throwerror-2?file=index.ts)

```javascript
import { of, throwError } from "rxjs";
import { concatMap } from "rxjs/operators";

const user$ = of(
  { name: "NyaGarcía", age: 23 },
  { name: "zaldih", age: 21 },
  { name: "caballerog", age: 35 },
  { name: "carla.1003", age: 17 }
);

user$
  .pipe(
    concatMap((user) =>
      user.age < 18 ? throwError("Menor de edad") : of(user)
    )
  )
  .subscribe(console.log, console.error);
// Salida: { name: "NyaGarcía", age: 23 }, { name: 'zaldih', age: 21 }, { name: "caballerog", age: 35 }, (error) Menor de edad
```

### Ejemplos de la documentación oficial

**Emitir el número 7 y después un Error**

```javascript
import { throwError, concat, of } from "rxjs";

const result = concat(of(7), throwError(new Error("oops!")));
result.subscribe(
  (x) => console.log(x),
  (e) => console.error(e)
);

// Salida: 7, (error) Error: oops!
```

**Proyectar cada número a la secuencia 'a', 'b', 'c', lanzando un error para el número 2**

```javascript
import { throwError, interval, of } from "rxjs";
import { mergeMap } from "rxjs/operators";

interval(1000)
  .pipe(
    mergeMap((x) =>
      x === 2 ? throwError("El número 2 no mola") : of("a", "b", "c")
    )
  )
  .subscribe(
    (x) => console.log(x),
    (e) => console.error(e)
  );

// Salida:
// a
// b
// c
// a
// b
// c
// (error) El número 2 no mola
```

### Recursos adicionales

[![Source code](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/creation/assets/icons/source-code.png)](https://github.com/ReactiveX/rxjs/blob/master/src/internal/observable/throwError.ts)

[Documentación oficial en inglés](https://rxjs.dev/api/index/function/throwError)


# timer

Crea un Observable que comienza a emitir una secuencia ascendente de números consecutivos a intervalos, tras un periodo inicial de tiempo

<details>

<summary>Signatura</summary>

#### Firma

`timer(dueTime: number | Date = 0, periodOrScheduler?: number | SchedulerLike, scheduler?: SchedulerLike): Observable<number>`

#### Parámetros

#### Retorna

`Observable<number>`: Un Observable que emite una secuencia ascendente de números consecutivos, comenzando por el valor 0, tras un periodo de tiempo inicial especificado por `dueTime`.

</details>

## Descripción

Es como `interval`, pero se puede especificar cuándo deben comenzar las emisiones.

![Diagrama de canicas de timer](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/creation/assets/images/marble-diagrams/creation/timer.png)

`timer` retorna un Observable que emite una secuencia de números ascendentes infinita. Los valores se emiten a intervalos constantes de tiempo, según se especifique. La primera emisión ocurre tras el periodo de tiempo especificado por `dueTime`. Este periodo inicial de espera también se puede proporcionar en formato `Date`.

Por defecto, este operador utiliza el `SchedulerLike` `asyncScheduler` para proporcionar la noción del tiempo, pero se le puede proporcionar cualquier otro `SchedulerLike`.

Si no se proporciona el valor `period`, el Observable resultante emite un único valor, 0. Si se proporciona un valor `period`, se emite una secuencia infinita.

## Ejemplos

**Emitir un único valor, 0, tras 2 segundos de espera**

[StackBlitz](https://stackblitz.com/edit/docu-rxjs-timer?file=index.ts)

```javascript
import { timer } from "rxjs";

const zero$ = timer(2000);

zero$.subscribe(console.log);
// Salida: 0
```

**Emitir una secuencia ascendente de números a intervalos de 1 segundo, tras 5 segundos de espera**

[StackBlitz](https://stackblitz.com/edit/docu-rxjs-timer-2?file=index.ts)

```javascript
import { timer } from "rxjs";

const number$ = timer(5000, 1000);

number$.subscribe((number) => console.log(number));
// Output: 0, 1, 2, 3...
```

### Ejemplos de la documentación oficial

**Emitir una secuencia ascendente de números, uno cada segundo (1000ms), comenzando tras 3 segundos**

```javascript
import { timer } from "rxjs";

const numbers = timer(3000, 1000);
numbers.subscribe((x) => console.log(x));
```

Emitir el número 0 tras 5 segundos de espera

```javascript
import { timer } from "rxjs";

const numbers = timer(5000);
numbers.subscribe((x) => console.log(x));
```

### Recursos adicionales

[![Source code](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/creation/assets/icons/source-code.png)](https://github.com/ReactiveX/rxjs/blob/master/src/internal/observable/timer.ts)

[Documentación oficial en inglés](https://rxjs.dev/api/index/function/timer)


# Gestión de Errores

* [catchError](/operadores/error-handling/catcherror)
* [retry](/operadores/error-handling/retry)

## Operadores Obsoletos

* [retryWhen](/operadores/error-handling/retrywhen) (obsoleto)


# catchError

Captura errores en el Observable que se manejan devolviendo un Observable nuevo o lanzando un error

<details>

<summary>Signatura</summary>

#### Firma

`catchError<T, O extends ObservableInput<any>>(selector: (err: any, caught: Observable<T>) => O): OperatorFunction<T, T | ObservedValueOf<O>>`

#### Parámetros

#### Retorna

`OperatorFunction<T, T | ObservedValueOf<O>>`: Un Observable que se puede originar en el Observable fuente o en el Observable retornado por la función `selector`.

</details>

## Descripción

`catchError` captura errores en el Observable fuente, manejándolos de dos maneras posibles: bien devolviendo un Observable nuevo o bien lanzando un nuevo error.

![Diagrama de canicas del operador catchError](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/error-handling/assets/images/marble-diagrams/error-handling/catchError.png)

## Ejemplos

**Capturar un error, retornando un Observable**

[StackBlitz](https://stackblitz.com/edit/docu-rxjs-catcherror?file=index.ts)

```javascript
import { throwError, of } from "rxjs";
import { catchError } from "rxjs/operators";

const error$ = throwError("¡Oh no!");

error$
  .pipe(catchError((error) => of(`Error capturado grácilmente: ${error}`)))
  .subscribe(console.log);
// Salida: Error capturado grácilmente: ¡Oh no!
```

**Capturar un error y lanzar otro error**

[StackBlitz](https://stackblitz.com/edit/docu-rxjs-catcherror-2?file=index.ts)

```javascript
import { throwError, of } from "rxjs";
import { catchError } from "rxjs/operators";

const error$ = throwError("Oh no!");

error$
  .pipe(
    catchError((error) => {
      throw `Lanzando un nuevo error: ${error}`;
    })
  )
  .subscribe(console.log, console.error);
// Salida: (Error) Lanzando un nuevo error: Oh no!
```

**Capturar los errores de un Observable interno**

Al capturar los errores que ocurren en un Observable interno (un Observable emitido por un Observable de orden superior), se debe tener cuidado a la hora de utilizar el operador `catchError` ya que, si se coloca en el sitio equivocado, el flujo del Observable fuente no seguirá ejecutándose tras capturar el error.

A continuación, se puede ver cómo el uso incorrecto de `catchError` hará que, después de capturar el error que devuelve la primera petición, el flujo se completará y no se harán las otras dos peticiones restantes:

[StackBlitz](https://stackblitz.com/edit/docu-rxjs-catcherror-inner?file=index.ts)

```javascript
import { map, concatMap, catchError } from "rxjs/operators";
import { ajax } from "rxjs/ajax";
import { of } from "rxjs";

const pokemonId$ = of(-3, 5, 6);

function getPokemonName(id: number) {
  return ajax
    .getJSON(`https://pokeapi.co/api/v2/pokemon/${id}`)
    .pipe(map(({ name }) => name));
}

pokemonId$
  .pipe(
    concatMap((id) => getPokemonName(id)),
    catchError((error) => of(`¡Oh no, ha ocurrido un error! ${error}`))
  )
  .subscribe(console.log, console.error, () => console.log("Completado"));
// Salida: ¡Oh no, ha ocurrido un error! AjaxError: ajax error 404, Completado
```

Sin embargo, si se utiliza `catchError` en el Observable interno, el comportamiento es el que se busca: cuando falle la primera petición, se capturará el error y el flujo seguirá ejecutándose, realizando las dos peticiones restantes:

[StackBlitz](https://stackblitz.com/edit/docu-rxjs-catcherror-inner-2?file=index.ts)

```javascript
import { map, concatMap, catchError } from "rxjs/operators";
import { ajax } from "rxjs/ajax";
import { of } from "rxjs";

const pokemonId$ = of(-3, 5, 6);

function getPokemonName(id: number) {
  return ajax
    .getJSON(`https://pokeapi.co/api/v2/pokemon/${id}`)
    .pipe(map(({ name }) => name));
}

pokemonId$
  .pipe(
    concatMap((id) =>
      getPokemonName(id).pipe(catchError((error) => of(`¡Oh no! ${error}`)))
    )
  )
  .subscribe(console.log, console.error, () => console.log("Completado"));
// Salida: ¡Oh no, ha ocurrido un error!, charmeleon, charizard, Completado
```

### Ejemplos de la documentación oficial

**Continuar con un Observable diferente cuando ocurre un error**

```javascript
import { of } from "rxjs";
import { map, catchError } from "rxjs/operators";

of(1, 2, 3, 4, 5)
  .pipe(
    map((n) => {
      if (n === 4) {
        throw "four!";
      }
      return n;
    }),
    catchError((err) => of("I", "II", "III", "IV", "V"))
  )
  .subscribe((x) => console.log(x));
// 1, 2, 3, I, II, III, IV, V
```

**Reiniciar el Observable fuente en caso de error, parecido al operador retry()**

```javascript
import { of } from "rxjs";
import { map, catchError, take } from "rxjs/operators";

of(1, 2, 3, 4, 5)
  .pipe(
    map((n) => {
      if (n === 4) {
        throw "four!";
      }
      return n;
    }),
    catchError((err, caught) => caught),
    take(30)
  )
  .subscribe((x) => console.log(x));
// 1, 2, 3, 1, 2, 3...
```

**Lanzar un error nuevo cuando el Observable fuente lance un error**

```javascript
import { of } from "rxjs";
import { map, catchError } from "rxjs/operators";

of(1, 2, 3, 4, 5)
  .pipe(
    map((n) => {
      if (n === 4) {
        throw "four!";
      }
      return n;
    }),
    catchError((err) => {
      throw "error en la fuente. Detalles: " + err;
    })
  )
  .subscribe(
    (x) => console.log(x),
    (err) => console.log(err)
  );
// 1, 2, 3, error en la fuente. Detalles: four!
```

### Recursos adicionales

[![Source code](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/error-handling/assets/icons/source-code.png)](https://github.com/ReactiveX/rxjs/blob/master/src/internal/operators/catchError.ts)

[Documentación oficial en inglés](https://rxjs.dev/api/operators/catchError)


# retry

Reintenta una secuencia Observable un número determinado de veces en el caso de que ocurra un error

💡 retry es muy útil para reintentar peticiones HTTP

<details>

<summary>Signatura</summary>

#### Firma

`retry<T>(count: number = -1): MonoTypeOperatorFunction<T>`

#### Parámetros

#### Retorna

`MonoTypeOperatorFunction<T>`: El Observable fuente modificado con la lógica de reintento.

</details>

## Descripción

Retorna un Observable que refleja el Observable fuente con la excepción de un error. Si el Observable fuente lanza un error, este operador se resuscribirá al Observable fuente durante un máximo de `count` veces, antes de propagar el error.

![Diagrama de canicas del operador retry](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/error-handling/assets/images/marble-diagrams/error-handling/retry.png)

Todos los valores emitidos por el Observable fuente se emitirán en el Observable resultante, incluso aquellos que se emitan durante suscripciones fallidas. Por ejemplo, si un Observable emite los valores `[1, 2]` y falla, y al segundo intento consigue completarse, emitiendo los valores `[1, 2, 3, 4, 5]`, las notificaciones del Observable resultante serían: `[1, 2, 1, 2, 3, 4, 5, complete]`.

## Ejemplos

**Reintentar una petición Ajax 3 veces en el caso de que haya algún error**

[StackBlitz](https://stackblitz.com/edit/docu-rxjs-retry?file=index.ts)

```javascript
import { retry } from "rxjs/operators";
import { ajax } from "rxjs/ajax";

const ghibliFilm$ = ajax.getJSON(`https://ghibliapi.herokuapp.com/fi`);

ghibliFilm$.pipe(retry(3)).subscribe(console.log, console.error);
// Salida: (error) Error: ajax error 404
```

**Utilizar `retry` junto a `catchError` para que, en el caso de que los tres reintentos de la petición Ajax fallen, el flujo continúe en lugar de acabar en error.**

[StackBlitz](https://stackblitz.com/edit/docu-rxjs-retry-2?file=index.ts)

```javascript
import { catchError, concatMap, map, retry } from "rxjs/operators";
import { ajax } from "rxjs/ajax";
import { of } from "rxjs";

const pokemonId$ = of(-3, 5, 6);

function getPokemonName(id: number) {
  return ajax.getJSON(`https://pokeapi.co/api/v2/pokemon/${id}`).pipe(
    map(({ name }) => name),
    // Se reintentará 3 veces si ocurre un error
    retry(3),
    // En el caso de que los 3 reintentos fallen, se usa catchError para que el flujo continúe
    catchError((error) =>
      of(`Reintentado 3 veces, pero ha ocurrido un error: ${error.message}`)
    )
  );
}

pokemonId$
  .pipe(concatMap((id) => getPokemonName(id)))
  .subscribe(console.log, console.error, () => console.log("¡Completado!"));
/* Salida:
'Reintentado 3 veces, pero ha ocurrido un error: ajax error 404',
'charmeleon', 
'charizard', 
'¡Completado!' 
*/
```

### Ejemplo de la documentación oficial en inglés

```javascript
import { interval, of, throwError } from "rxjs";
import { mergeMap, retry } from "rxjs/operators";

const source = interval(1000);
const example = source.pipe(
  mergeMap((val) => {
    if (val > 5) {
      return throwError("Error!");
    }
    return of(val);
  }),
  // Reintentar 2 veces cuando se lance un error
  retry(2)
);

const subscribe = example.subscribe({
  next: (val) => console.log(val),
  error: (val) => console.log(`${val}: Retried 2 times then quit!`),
});

// Salida:
// 0..1..2..3..4..5..
// 0..1..2..3..4..5..
// 0..1..2..3..4..5..
// "Error!: Retried 2 times then quit!"
```

### Recursos adicionales

[![Source code](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/error-handling/assets/icons/source-code.png)](https://github.com/ReactiveX/rxjs/blob/master/src/internal/operators/retry.ts)

[Documentación oficial en inglés](https://rxjs.dev/api/operators/retry)


# retryWhen

Reintenta una secuencia Observable cuando ocurre un error

<details>

<summary>Signatura</summary>

#### Firma

`retryWhen<T>(notifier: (errors: Observable<any>) => Observable<any>): MonoTypeOperatorFunction<T>`

#### Parámetros

#### Retorna

`MonoTypeOperatorFunction<T>`: El Observable fuente modificado con la lógica de reintento.

</details>

## Descripción

Retorna un Observable que refleja el Observable fuente con la excepción de un error. Si el Observable fuente lanza un error, `retryWhen` emitirá el `Throwable` que provocó el error al Observable retornado por `notifier`. Si ese Observable hace una llamada a `complete` o a `error`, entonces este operador llamará a `complete` o a `error` en la suscripción hija. En caso contrario, `retryWhen` se resuscribirá al Observable fuente.

![Diagrama de canicas del operador retryWhen](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/error-handling/assets/images/marble-diagrams/error-handling/retryWhen.png)

## Ejemplos

**Reintentar una secuencia Observable tras esperar un tiempo determinado, sin un número limitado de intentos**

[StackBlitz](https://stackblitz.com/edit/docu-rxjs-retrywhen?file=index.ts)

```javascript
import { interval, timer, throwError } from "rxjs";
import { map, tap, retryWhen, delay } from "rxjs/operators";

const number$ = interval(1000);
const delayMilliseconds = 3000;

number$
  .pipe(
    map((n) => {
      if (n > 5) {
        throw "Número demasiado alto";
      }
      return n;
    }),
    retryWhen((error$) =>
      error$.pipe(
        tap((err) => console.log(`Ha ocurrido un error: ${err}`)),
        // Reintentar después de 3s
        delay(delayMilliseconds)
      )
    )
  )
  .subscribe(console.log);
// Salida: 0, 1, 2, 3, 4, 5, Ha ocurrido un error: Número demasiado alto (3s después se repite el proceso) 0, 1...
```

**Reintentar una secuencia Observable tras esperar un tiempo determinado, con un número limitado de intentos**

[StackBlitz](https://stackblitz.com/edit/docu-rxjs-retrywhen-2?file=index.ts)

```javascript
import {
  catchError,
  concatMap,
  map,
  mergeMap,
  retryWhen,
} from "rxjs/operators";
import { ajax } from "rxjs/ajax";
import { of, throwError, timer } from "rxjs";

const pokemonId$ = of(-3, 5, 6);

const maxTries = 2;
const delayMilliseconds = 3000;

function getPokemonName(id: number) {
  return ajax.getJSON(`https://pokeapi.co/api/v2/pokemon/${id}`).pipe(
    map(({ name }) => name),
    retryWhen((error$) =>
      error$.pipe(
        mergeMap((error, tries) =>
          // Si no se han gastado todos los intentos, se volverá a reintentar. En caso contrario, se lanzará un error
          tries < maxTries ? timer(delayMilliseconds) : throwError(error)
        )
      )
    ),
    // Capturando el error
    catchError((error) =>
      of(
        `Reintentado ${maxTries} veces, con un retraso de ${delayMilliseconds}ms, pero ha ocurrido un error: ${error.message}`
      )
    )
  );
}

pokemonId$
  .pipe(concatMap((id) => getPokemonName(id)))
  .subscribe(console.log, console.error, () => console.log("¡Completado!"));
// Salida: 'Reintentado 2 veces, con un retraso de 3000ms, pero ha ocurrido un error: ajax error 404', 'charmeleon', 'charizard', '¡Completado!'
```

### Recursos adicionales

[![Source code](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/error-handling/assets/icons/source-code.png)](https://github.com/ReactiveX/rxjs/blob/master/src/internal/operators/retryWhen.ts)

[Documentación oficial en inglés](https://rxjs.dev/api/operators/retryWhen)


# Filtración

* [audit](/operadores/filtering/audit)
* [auditTime](/operadores/filtering/audittime)
* [debounce](/operadores/filtering/debounce)
* [debounceTime](/operadores/filtering/debouncetime)
* [distinct](/operadores/filtering/distinct)
* [distinctUntilChanged](/operadores/filtering/distinctuntilchanged)
* [distinctUntilKeyChanged](/operadores/filtering/distinctuntilkeychanged)
* [elementAt](/operadores/filtering/elementat)
* [filter](/operadores/filtering/filter)
* [first](/operadores/filtering/first)
* [ignoreElements](/operadores/filtering/ignoreelements)
* [last](/operadores/filtering/last)
* [sample](/operadores/filtering/sample)
* [sampleTime](/operadores/filtering/sampletime)
* [single](/operadores/filtering/single)
* [skip](/operadores/filtering/skip)
* [skipLast](/operadores/filtering/skiplast)
* [skipUntil](/operadores/filtering/skipuntil)
* [skipWhile](/operadores/filtering/skipwhile)
* [take](/operadores/filtering/take)
* [takeLast](/operadores/filtering/takelast)
* [takeUntil](/operadores/filtering/takeuntil)
* [takeWhile](/operadores/filtering/takewhile)
* [throttle](/operadores/filtering/throttle)
* [throttleTime](/operadores/filtering/throttletime)


# audit

Ignora los valores emitidos por la fuente durante un periodo de tiempo cuya duración está determinada por un segundo Observable. Pasado este tiempo, emite el valor más reciente y repite el proceso

<details>

<summary>Signatura</summary>

#### Firma

`audit<T>(durationSelector: (value: T) => SubscribableOrPromise<any>): MonoTypeOperatorFunction<T>`

#### Parámetros

#### Retorna

`MonoTypeOperatorFunction<T>`: Un Observable que limita las emisiones del Observable fuente.

</details>

## Descripción

Es como `auditTime`, pero la duración del silenciamiento está determinada por un segundo Observable.

![Diagrama de canicas del operador audit](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/filtering/assets/images/marble-diagrams/filtering/audit.png)

`audit` es similar a `throttle`, pero emite el último valor del periodo de silenciamiento, en lugar del primero. `audit` emite el valor más reciente del Observable fuente en cuanto su temporizador interno se deshabilita, e ignora los valores de la fuente mientras el temporizador está habilitado. Inicialmente, el temporizador está deshabilitado. En cuanto llega el primer valor de la fuente, se habilita el temporizador mediante una llamada a la función `durationSelector` con dicho valor, que retorna el Observable de 'duración'. Cuando el Observable de duración emita un valor o se complete, el temporizador se deshabilitará, y el valor más reciente emitido por el Observable fuente se emitirá en el Observable resultante. Este proceso se repite con cada valor de la fuente.

## Ejemplos

**Ignorar las teclas pulsadas durante 2s, y emitir la última tecla pulsada. Repetir el proceso.**

[StackBlitz](https://stackblitz.com/edit/rxjs-audit-1?file=index.ts)

```typescript
import { audit } from "rxjs/operators";
import { fromEvent, interval } from "rxjs";

const key$ = fromEvent<KeyboardEvent>(document, "keydown");

// Ignorar las teclas pulsadas durante 2s, y emitir la última tecla pulsada. Repetir el proceso.
key$
  .pipe(audit(() => interval(2000)))
  .subscribe(({ code }) => console.log(code));
// Salida: (Pulsar tecla y) (Pulsar tecla x) (2s) KeyX (Pulsar tecla o) (2s) KeyO...
```

### Ejemplo de la documentación oficial

**Emite clicks a un ritmo de, como mucho, un click por segundo**

```javascript
import { fromEvent, interval } from "rxjs";
import { audit } from "rxjs/operators";

const clicks = fromEvent(document, "click");
const result = clicks.pipe(audit((ev) => interval(1000)));
result.subscribe((x) => console.log(x));
```

### Recursos adicionales

[![Source code](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/filtering/assets/icons/source-code.png)](https://github.com/ReactiveX/rxjs/blob/master/src/internal/operators/audit.ts)

[Documentación oficial en inglés](https://rxjs.dev/api/operators/audit)


# auditTime

Ignora los valores de la fuente durante un periodo de tiempo, tras el cual emite el valor más reciente del Observable fuente

<details>

<summary>Signatura</summary>

#### Firma

`auditTime<T>(duration: number, scheduler: SchedulerLike = async): MonoTypeOperatorFunction<T>`

#### Parámetros

#### Retorna

`MonoTypeOperatorFunction<T>`: Un Observable que limita las emisiones del Observable fuente.

</details>

## Descripción

Cuando recibe un valor de la fuente, lo ignora, además de todos los valores posteriores durante un periodo de tiempo. Una vez finalizado el periodo de tiempo, emite el valor más reciente del Observable fuente.

![Diagrama de canicas del operador auditTime](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/filtering/assets/images/marble-diagrams/filtering/auditTime.png)

auditTime es similar a throttleTime, pero emite el último valor del periodo de silenciamiento, en lugar del primero. auditTime emite el valor más reciente del Observable fuente en cuanto su temporizador interno se deshabilita, e ignora los valores de la fuente mientras el temporizador está habilitado. Inicialmente, el temporizador está deshabilitado. En cuanto llega el primer valor de la fuente, se habilita el temporizador. Tras un periodo de tiempo, determinado por `duration`, se deshabilita el temporizador y se emite el valor más reciente que haya emitido la fuente, en el Observable resultante. Este proceso se repite con cada valor de la fuente. auditTime puede recibir un SchedulerLike opcional para gestionar los temporizadores.

## Ejemplos

**Ignorar las teclas pulsadas durante un periodo de 2s, tras el cual emitir la última tecla pulsada. Repetir.**

[StackBlitz](https://stackblitz.com/edit/rxjs-audittime-1?file=index.ts)

```typescript
import { auditTime } from "rxjs/operators";
import { fromEvent } from "rxjs";

const key$ = fromEvent<KeyboardEvent>(document, "keydown");

key$.pipe(auditTime(2000)).subscribe(({ code }) => console.log(code));
// Salida: (2s) KeyX (2s) KeyO...
```

### Ejemplo de la documentación oficial

**Emite como mucho un click por segundo**

```javascript
import { fromEvent } from "rxjs";
import { auditTime } from "rxjs/operators";

const clicks = fromEvent(document, "click");
const result = clicks.pipe(auditTime(1000));
result.subscribe((x) => console.log(x));
```

### Recursos adicionales

[![Source code](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/filtering/assets/icons/source-code.png)](https://github.com/ReactiveX/rxjs/blob/master/src/internal/operators/auditTime.ts)

[Documentación oficial en inglés](https://rxjs.dev/api/operators/auditTime)


# debounce

Emite un valor del Observable fuente si, y solo si, pasa un periodo de tiempo determinado por otro Observable sin que el Observable fuente emita ningún valor

<details>

<summary>Signatura</summary>

#### Firma

`debounce<T>(durationSelector: (value: T) => SubscribableOrPromise<any>): MonoTypeOperatorFunction<T>`

#### Parámetros

#### Retorna

`MonoTypeOperatorFunction<T>`: Un Observable que retrasa las emisiones del Observable fuente durante un periodo de tiempo determinado por el Observable retornado por `durationSelector`. Es posible que algunos valores se pierdan si se producen demasiado frecuentemente.

</details>

## Descripción

Es como `debounceTime`, pero el periodo de silenciamiento de emisiones está determinado por un segundo Observable.

![Diagrama de canicas del operador debounce](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/filtering/assets/images/marble-diagrams/filtering/debounce.png)

`debounce` retrasa los valores emitidos por el Observable fuente, eliminando las emisiones almacenadas que estén pendientes de ser emitidas si el Observable fuente emite algún valor. Este operador almacena el valor más reciente emitido por el Observable fuente, y genera un Observable 'de duración' mediante una llamada a la función `durationSelector`. El valor almacenado se emite una vez que el Observable de duración emite un valor o se completa, y si el Observable fuente no ha emitido ningún valor desde la creación del Observable de duración. Si el Observable fuente emite un valor antes de que el Observable de duración emita o se complete, el valor almacenado será eliminado, y nunca se emitirá en el Observable resultante.

Al igual que `debouncetime`, este es un operador de limitación de emisiones, y también un operador similar a `delay`, ya que las emisiones del Observable resultante no tienen por qué ocurrir en el mismo momento en el que ocurrieron en el Observable fuente.

## Ejemplos

**Emitir la tecla pulsada más reciente, tras una sucesión rápida de teclas. Por ejemplo, si escribimos 'RxJS mola' muy rápidamente (con menos de 500ms entre pulsaciones), solo se emitirá la última letra (a)**

[StackBlitz](https://stackblitz.com/edit/rxjs-debounce-1?file=index.ts)

```typescript
import { debounce } from "rxjs/operators";
import { interval, fromEvent } from "rxjs";

const key$ = fromEvent<KeyboardEvent>(document, "keydown");

key$
  .pipe(debounce(() => interval(500)))
  .subscribe(({ code }) => console.log(code));
// Salida: KeyA
```

**Emitir la posición del último click tras una sucesión rápida de clicks**

[StackBlitz](https://stackblitz.com/edit/rxjs-debounce-2?file=index.ts)

```typescript
import { debounce } from "rxjs/operators";
import { interval, fromEvent } from "rxjs";

const click$ = fromEvent<MouseEvent>(document, "click");

click$
  .pipe(debounce(() => interval(1000)))
  .subscribe(({ screenX, screenY }) =>
    console.log(
      `Tu último click ha sido en la posición x: ${screenX}, y: ${screenY}`
    )
  );
// Salida: Tu último click ha sido en la posición x: 1278 , y: 265
```

### Ejemplo de la documentación oficial

**Emitir el click más reciente tras una sucesión rápida de clicks**

```javascript
import { fromEvent, interval } from "rxjs";
import { debounce } from "rxjs/operators";

const clicks = fromEvent(document, "click");
const result = clicks.pipe(debounce(() => interval(1000)));
result.subscribe((x) => console.log(x));
```

### Recursos adicionales

[![Source code](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/filtering/assets/icons/source-code.png)](https://github.com/ReactiveX/rxjs/blob/master/src/internal/operators/debounce.ts)

[Documentación oficial en inglés](https://rxjs.dev/api/operators/debounce)


# debounceTime

Emite un valor del Observable fuente si, y solo si, pasa un periodo de tiempo determinado sin que este emita ningún valor

<details>

<summary>Signatura</summary>

#### Firma

`debounceTime<T>(dueTime: number, scheduler: SchedulerLike = async): MonoTypeOperatorFunction<T>`

#### Parámetros

#### Retorna

`MonoTypeOperatorFunction<T>`: Un Observable que retrasa la emisiones del Observable fuente en un periodo de tiempo especificado por `dueTime`. Es posible que algunos valores sean eliminados si se emiten con demasiada frecuencia.

</details>

## Descripción

Es como `delay`, pero emite únicamente el valor más reciente de una sucesión de emisiones.

![Diagrama de canicas del operador debounceTime](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/filtering/assets/images/marble-diagrams/filtering/debounce.png)

`debounceTime` retrasa los valores del Observable fuente, eliminando las emisiones almacenadas pendientes de ser emitidas si el Observable fuente emite algún valor. Este operador almacena el valor más reciente del Observable fuente, y lo emite solo si ha pasado un periodo de tiempo, indicado por `dueTime`, sin que el Observable fuente emita ningún valor. Si el Observable fuente emite un valor antes de que pase el periodo de tiempo `dueTime`, el valor almacenado será eliminado, y nunca se emitirá en el Observable resultante.

Este es un operador de limitación de emisiones, ya que es imposible que se emita más de un valor en cualquiera de las ventanas de tiempo de duración `dueTime`, pero también es un operador similar a `delay`, ya que las emisiones de salida no ocurren en el mismo momento en el que se emitieron en el Observable fuente.

Recibe un `SchedulerLike` opcional para manejar los temporizadores.

## Ejemplos

**Emitir la tecla pulsada más reciente, tras una sucesión rápida de teclas. Por ejemplo, si escribimos 'RxJS mola' muy rápidamente (con menos de 500ms entre pulsaciones), solo se emitirá la última letra (a)**

[StackBlitz](https://stackblitz.com/edit/rxjs-debouncetime-1?file=index.ts)

```typescript
import { debounceTime } from "rxjs/operators";
import { fromEvent } from "rxjs";

const key$ = fromEvent<KeyboardEvent>(document, "keydown");

key$.pipe(debounceTime(500)).subscribe(({ code }) => console.log(code));
// Salida: KeyE
```

**Emitir la posición del último click tras una sucesión rápida de clicks**

[StackBlitz](https://stackblitz.com/edit/rxjs-debouncetime-2?file=index.ts)

```typescript
import { debounceTime } from "rxjs/operators";
import { fromEvent } from "rxjs";

const click$ = fromEvent<MouseEvent>(document, "click");

click$
  .pipe(debounceTime(1000))
  .subscribe(({ screenX, screenY }) =>
    console.log(
      `Tu último click fue en la posición x: ${screenX}, y: ${screenY}`
    )
  );
// Salida: Tu último click fue en la posición x: 1278 , y: 265
```

### Ejemplo de la documentación oficial

**Emite el click más reciente tras una sucesión de clicks**

```javascript
import { fromEvent } from "rxjs";
import { debounceTime } from "rxjs/operators";

const clicks = fromEvent(document, "click");
const result = clicks.pipe(debounceTime(1000));
result.subscribe((x) => console.log(x));
```

### Recursos adicionales

[![Source code](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/filtering/assets/icons/source-code.png)](https://github.com/ReactiveX/rxjs/blob/master/src/internal/operators/debounceTime.ts)

[Documentación oficial en inglés](https://rxjs.dev/api/operators/debounceTime)


# distinct

Retorna un Observable que emite todos los elementos del Observable fuente que sean distintos a los elementos anteriores

<details>

<summary>Signatura</summary>

#### Firma

`distinct<T, K>(keySelector?: (value: T) => K, flushes?: Observable<any>): MonoTypeOperatorFunction<T>`

#### Parámetros

#### Retorna

`MonoTypeOperatorFunction<T>`: Un Observable que emite elementos del Observable fuente de distinto valor.

</details>

## Descripción

Si se proporciona una función `keySelector`, se proyectará cada valor emitido por el Observable fuente a un nuevo valor, que se comparará con los valores previamente emitidos para ver si es distinto o no. Si no se proporciona una función `keySelector`, se compararán los valores emitidos por el Observable fuente directamente con las emisiones previas.

En los entornos de ejecución de JavaScript que den soporte a `Set`, `distinct` utilizará un `Set` para mejorar el rendimiento de la comprobación de distinción.

En otros entornos de ejecución, `distinct` utilizará una implementación mínima de `Set` que depende de un Array y de `indexOf`, por lo que el rendimiento empeorará de forma directamente proporcional a la cantidad de valores que se proporcionen. Incluso en los navegadores más modernos, un `distinct` ejecutándose durante un periodo largo de tiempo puede provocar fugas de memoria. Para minimizar este efecto en algunos escenarios, se puede proporcionar un parámetro `flushes` opcional para reiniciar el `Set` interno, eliminando todos sus valores.

## Ejemplos

**Usar distinct sin un selector**

[StackBlitz](https://stackblitz.com/edit/rxjs-distinct-1?file=index.ts)

```javascript
import { distinct } from "rxjs/operators";
import { of } from "rxjs";

const fruit$ = of(
  "Fresa",
  "Cereza",
  "Cereza",
  "Arándano",
  "Fresa",
  "Arándano",
  "Cereza"
);

fruit$.pipe(distinct()).subscribe(console.log);
// Salida: Fresa, Cereza, Arándano
```

**Usar distinct con un selector de clave**

[StackBlitz](https://stackblitz.com/edit/rxjs-distinct-2?file=index.ts)

```javascript
import { distinct } from "rxjs/operators";
import { of } from "rxjs";

const language$ = of(
  { name: "Java", type: "Orientado a objetos" },
  { name: "Ruby", type: "Multiparadigma" },
  { name: "Ruby", type: "Multiparadigma" },
  { name: "Haskell", type: "Funcional" },
  { name: "Haskell", type: "Funcional" },
  { name: "Java", type: "Orientado a objetos" },
  { name: "Ruby", type: "Multiparadigma" }
);

language$.pipe(distinct(({ name }) => name)).subscribe(console.log);
/* Salida: 
{ name: "Java", type: "Orientado a objetos" }, 
{ name: "Ruby", type: "Multiparadigma" }, 
{ name: "Haskell", type: "Funcional" }
*/
```

### Ejemplos de la documentación oficial

**Un ejemplo simple con números**

```javascript
import { of } from "rxjs";
import { distinct } from "rxjs/operators";

of(1, 1, 2, 2, 2, 1, 2, 3, 4, 3, 2, 1)
  .pipe(distinct())
  .subscribe((x) => console.log(x)); // 1, 2, 3, 4
```

**Un ejemplo utilizando la función keySelector**

```typescript
import { of } from "rxjs";
import { distinct } from "rxjs/operators";

interface Person {
  age: number;
  name: string;
}

of<Person>(
  { age: 4, name: "Foo" },
  { age: 7, name: "Bar" },
  { age: 5, name: "Foo" }
)
  .pipe(distinct((p: Person) => p.name))
  .subscribe((x) => console.log(x));

// Salida:
// { age: 4, name: 'Foo' }
// { age: 7, name: 'Bar' }
```

### Recursos adicionales

[![Source code](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/filtering/assets/icons/source-code.png)](https://github.com/ReactiveX/rxjs/blob/master/src/internal/operators/distinct.ts)

[Documentación oficial en inglés](https://rxjs.dev/api/operators/distinct)


# distinctUntilChanged

Retorna un Observable que emite todos los elementos emitidos por el Observable fuente que sean distintos al valor anterior

<details>

<summary>Signatura</summary>

#### Firma

`distinctUntilChanged<T, K>(compare?: (x: K, y: K) => boolean, keySelector?: (x: T) => K): MonoTypeOperatorFunction<T>`

#### Parámetros

#### Retorna

`MonoTypeOperatorFunction<T>`: Un Observable que emite elementos del Observable fuente que tengan valores distintos.

</details>

## Descripción

Si se proporciona una función de comparación, se utilizará para comprobar si cada elemento se debe emitir o no.

Si no se proporciona una función de comparación, se utiliza una verificación de igualdad.

## Ejemplos

**Usar distinctUntilChanged\` sin una función de comparación**

[StackBlitz](https://stackblitz.com/edit/rxjs-distinctuntilchanged-1?file=index.ts)

```javascript
import { distinctUntilChanged } from "rxjs/operators";
import { of } from "rxjs";

const fruit$ = of("Fresa", "Cereza", "Cereza", "Arándano", "Arándano", "Fresa");

fruit$.pipe(distinctUntilChanged()).subscribe(console.log);
// Salida: Fresa, Cereza, Arándano, Fresa
```

**Usar distinctUntilChanged con una función de comparación**

[StackBlitz](https://stackblitz.com/edit/rxjs-distinctuntilchanged-2?file=index.ts)

```javascript
import { distinctUntilChanged } from "rxjs/operators";
import { of } from "rxjs";

const language$ = of(
  { name: "Java", type: "Orientado a objetos" },
  { name: "Ruby", type: "Multiparadigma" },
  { name: "Ruby", type: "Multiparadigma" },
  { name: "Haskell", type: "Funcional" },
  { name: "Haskell", type: "Funcional" },
  { name: "Java", type: "Orientado a objetos" },
  { name: "Ruby", type: "Multiparadigma" }
);

language$
  .pipe(
    distinctUntilChanged(
      ({ name: previousName }, { name }) => previousName === name
    )
  )
  .subscribe(console.log);
/* Salida: 
  { name: "Java", type: "Orientado a objetos" },
  { name: "Ruby", type: "Multiparadigma" },
  { name: "Haskell", type: "Funcional" },
  { name: "Java", type: "Orientado a objetos" },
  { name: "Ruby", type: "Multiparadigma" }
*/
```

### Ejemplos de la documentación oficial

**Un ejemplo simple con números**

```javascript
import { of } from "rxjs";
import { distinctUntilChanged } from "rxjs/operators";

of(1, 1, 2, 2, 2, 1, 1, 2, 3, 3, 4)
  .pipe(distinctUntilChanged())
  .subscribe((x) => console.log(x)); // 1, 2, 1, 2, 3, 4
```

**Un ejemplo usando una función de comparación**

```javascript
    import { of } from 'rxjs';
    import { distinctUntilChanged } from 'rxjs/operators';

    interface Person {
       age: number,
       name: string
    }

    of<Person>(
        { age: 4, name: 'Foo'},
        { age: 7, name: 'Bar'},
        { age: 5, name: 'Foo'},
        { age: 6, name: 'Foo'},
      ).pipe(
        distinctUntilChanged((p: Person, q: Person) => p.name === q.name),
      )
      .subscribe(x => console.log(x));

    // displays:
    // { age: 4, name: 'Foo' }
    // { age: 7, name: 'Bar' }
    // { age: 5, name: 'Foo' }
```

### Recursos adicionales

[![Source code](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/filtering/assets/icons/source-code.png)](https://github.com/ReactiveX/rxjs/blob/master/src/internal/operators/distinctUntilChanged.ts)

[Documentación oficial en inglés](https://rxjs.dev/api/operators/distinctUntilChanged)


# distinctUntilKeyChanged

Retorna un Observable que emite los elementos del Observable fuente cuya propiedad especificada sea distinta a la del elemento anterior

<details>

<summary>Signatura</summary>

#### Firma

`distinctUntilKeyChanged<T, K extends keyof T>(key: K, compare?: (x: T[K], y: T[K]) => boolean): MonoTypeOperatorFunction<T>`

#### Parámetros

#### Retorna

`MonoTypeOperatorFunction<T>`: Un Observable que emite elementos del Observable fuente si la propiedad especificada es distinta a la del elemento anterior.

</details>

## Descripción

Si se proporciona una función de comparación, se utilizará para comprobar si cada elemento se debe emitir o no.

Si no se proporciona una función de comparación, se utiliza una verificación de igualdad.

## Ejemplos

**Emitir solo cuando la tecla pulsada sea distinta a la tecla pulsada anterior**

[StackBlitz](https://stackblitz.com/edit/rxjs-distinctuntilkeychanged-1?file=index.ts)

```typescript
import { distinctUntilKeyChanged, map } from "rxjs/operators";
import { fromEvent } from "rxjs";

const key$ = fromEvent<KeyboardEvent>(document, "keydown").pipe(
  distinctUntilKeyChanged("code"),
  map(({ code }) => code)
);

key$.subscribe(console.log);
// Salida: (Pulsar tecla y) (Pulsar tecla x) 'KeyX'
```

**Emitir el objeto lenguaje si su propiedad name es distinta a la del objeto anterior**

[StackBlitz](https://stackblitz.com/edit/rxjs-distinctuntilkeychanged-2?file=index.ts)

```javascript
import { distinctUntilKeyChanged } from "rxjs/operators";
import { of } from "rxjs";

const language$ = of(
  { name: "Java", type: "Orientado a objetos" },
  { name: "Ruby", type: "Multiparadigma" },
  { name: "Ruby", type: "Multiparadigma" },
  { name: "Haskell", type: "Funcional" },
  { name: "Haskell", type: "Funcional" },
  { name: "Java", type: "Orientado a objetos" },
  { name: "Ruby", type: "Multiparadigma" }
);

language$.pipe(distinctUntilKeyChanged("name")).subscribe(console.log);
/* Salida:
  { name: "Java", type: "Orientado a objetos" },
  { name: "Ruby", type: "Multiparadigma" },
  { name: "Haskell", type: "Funcional" },
  { name: "Java", type: "Orientado a objetos" },
  { name: "Ruby", type: "Multiparadigma" }
*/
```

**Utilizar una función de comparación para ignorar las diferencias de mayúsculas/minúsculas**

[StackBlitz](https://stackblitz.com/edit/rxjs-distinctuntilkeychanged-3?file=index.ts)

```javascript
import { of } from "rxjs";
import { distinctUntilKeyChanged } from "rxjs/operators";

const user$ = of(
  { name: "NyaGarcía", age: 23 },
  { name: "nyagarcía", age: 23 },
  { name: "zaldih", age: 21 },
  { name: "caballerog", age: 35 },
  { name: "caballeroG", age: 35 }
);

user$
  .pipe(
    distinctUntilKeyChanged(
      "name",
      (prev, curr) => prev.toLowerCase() === curr.toLowerCase()
    )
  )
  .subscribe(console.log);
/* Salida: 
  { name: 'NyaGarcía', age: 23 }, 
  { name: 'zaldih', age: 21} , 
  { name: 'caballerog', age: 35 }
*/
```

### Ejemplos de la documentación oficial

**Un ejemplo comparando el campo name**

```typescript
import { of } from "rxjs";
import { distinctUntilKeyChanged } from "rxjs/operators";

interface Person {
  age: number;
  name: string;
}

of<Person>(
  { age: 4, name: "Foo" },
  { age: 7, name: "Bar" },
  { age: 5, name: "Foo" },
  { age: 6, name: "Foo" }
)
  .pipe(distinctUntilKeyChanged("name"))
  .subscribe((x) => console.log(x));

// Salida:
// { age: 4, name: 'Foo' }
// { age: 7, name: 'Bar' }
// { age: 5, name: 'Foo' }
```

**Un ejemplo comparando las primeras letras de la propiedad name**

```typescript
import { of } from "rxjs";
import { distinctUntilKeyChanged } from "rxjs/operators";

interface Person {
  age: number;
  name: string;
}

of<Person>(
  { age: 4, name: "Foo1" },
  { age: 7, name: "Bar" },
  { age: 5, name: "Foo2" },
  { age: 6, name: "Foo3" }
)
  .pipe(
    distinctUntilKeyChanged(
      "name",
      (x: string, y: string) => x.substring(0, 3) === y.substring(0, 3)
    )
  )
  .subscribe((x) => console.log(x));

// Salida:
// { age: 4, name: 'Foo1' }
// { age: 7, name: 'Bar' }
// { age: 5, name: 'Foo2' }
```

### Recursos adicionales

[![Source code](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/filtering/assets/icons/source-code.png)](https://github.com/ReactiveX/rxjs/blob/master/src/internal/operators/distinctUntilKeyChanged.ts)

[Documentación oficial en inglés](https://rxjs.dev/api/operators/distinctUntilKeyChanged)


# elementAt

Emite el valor que esté en la índice especificado en la secuencia de emisiones del Observable fuente

<details>

<summary>Signatura</summary>

#### Firma

`elementAt<T>(index: number, defaultValue?: T): MonoTypeOperatorFunction<T>`

#### Parámetros

#### Retorna

`MonoTypeOperatorFunction<T>`: Un Observable que emite un solo elemento, si lo encuentra. Si no, emite el valor por defecto en el caso de que se haya proporcionado uno. En caso contrario, se emite une error.

#### Lanza

`ArgumentOutOfRangeError` Al usar `elementAt(i)`, se lanza un `ArgumentOutOrRangeError` si `i < 0` o si el Observable se completa antes de emitir la i-ésima notificación.

</details>

## Descripción

Emite únicamente el valor i-ésimo, y se completa.

![Diagrama de canicas del operador elementAt](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/filtering/assets/images/marble-diagrams/filtering/elementAt.png)

`elementAt` retorna un Observable que emite el elemento en la posición indicada por el índice, o un valor por defecto si el índice proporcionado está fuera de rango y se proporciona dicho valor por defecto. En el caso de que no se proporcione, el Observable resultante emitirá un error `ArgumentOutOfRangeError`. s

## Ejemplos

**Emitir la segunda emisión del Observable fuente**

[StackBlitz](https://stackblitz.com/edit/rxjs-elementat-1?file=index.ts)

```javascript
import { of } from "rxjs";
import { elementAt } from "rxjs/operators";

const fruit$ = of("Cereza", "Fresa", "Arándano");

fruit$.pipe(elementAt(1)).subscribe(console.log);
// Salida: Fresa
```

**Si no se encuentra el índice y no se proporciona un valor por defecto, se lanza un error**

[StackBlitz](https://stackblitz.com/edit/rxjs-elementat-2?file=index.ts)

```javascript
import { of } from "rxjs";
import { elementAt } from "rxjs/operators";

const fruit$ = of("Cereza", "Fresa", "Arándano");

// Si no se encuentra el índice y no se proporciona un valor por defecto, se lanza un error
fruit$.pipe(elementAt(5)).subscribe(console.log, console.error);
// Salida: (error) Error: argument out of range
```

**Proporcionar un valor por defecto para que, si no se encuentra el índice especificado, no se lance un error**

[StackBlitz](https://stackblitz.com/edit/rxjs-elementat-3?file=index.ts)

```javascript
import { of } from "rxjs";
import { elementAt } from "rxjs/operators";

const defaultFruit = "Mora";

const fruit$ = of("Cereza", "Fresa", "Arándano");

// Proporcionar un valor por defecto para que, si no se encuentra el índice especificado, no se lance un error
fruit$.pipe(elementAt(5, defaultFruit)).subscribe(console.log, console.error);
// Salida: Mora
```

### Ejemplo de la documentación oficial

**Emitir solo el tercer evento click**

```javascript
import { fromEvent } from "rxjs";
import { elementAt } from "rxjs/operators";

const clicks = fromEvent(document, "click");
const result = clicks.pipe(elementAt(2));
result.subscribe((x) => console.log(x));

// Salida:
// click 1 = nada
// click 2 = nada
// click 3 = objeto MouseEvent
```

### Recursos adicionales

[![Source code](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/filtering/assets/icons/source-code.png)](https://github.com/ReactiveX/rxjs/blob/master/src/internal/operators/elementAt.ts)

[Documentación oficial en inglés](https://rxjs.dev/api/operators/elementAt)


# filter

Filtra elementos emitidos por el Observable fuente, emitiendo únicamente aquellos que cumplan una condición

<details>

<summary>Signatura</summary>

#### Firma

`filter<T>(predicate: (value: T, index: number) => boolean, thisArg?: any): MonoTypeOperatorFunction<T>`

#### Parámetros

#### Retorna

`MonoTypeOperatorFunction<T>`: Un Observable de valores del Observable fuente que han cumpliado la condición especificada por la función `predicate`.

</details>

## Descripción

Al igual que `Array.prototype.filter()`, solo emite un valor si cumple una condición determinada.

![Diagrama de canicas del operador filter](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/filtering/assets/images/marble-diagrams/filtering/filter.png)

Es similar al método `Array.prototype.filter()`. Este operador emite únicamente aquellos valores del Observable fuente que cumplan la condición especificada en la función `predicate`, es decir, aquellos valores que, al proporcionárselos a la función, hagan que esta devuelva `true`.

## Ejemplos

**Emitir los números mayores que 5**

[StackBlitz](https://stackblitz.com/edit/rxjs-filter-1?file=index.ts)

```javascript
import { filter } from "rxjs/operators";
import { range } from "rxjs";

const number$ = range(1, 10);

number$.pipe(filter((n) => n > 5)).subscribe(console.log);
// Salida: 6, 7, 8, 9, 10
```

**Emitir todas las teclas, excepto la barra espaciadora**

[StackBlitz](https://stackblitz.com/edit/rxjs-filter-2?file=index.ts)

```typescript
import { filter, map } from "rxjs/operators";
import { fromEvent } from "rxjs";

const key$ = fromEvent<KeyboardEvent>(document, "keydown");

key$
  .pipe(
    map(({ code }) => code),
    filter((code) => code !== "Space")
  )
  .subscribe(console.log);
// Salida: KeyX, KeyO...
```

**Filtrar los lenguages de tipo Multiparadigma**

[StackBlitz](https://stackblitz.com/edit/rxjs-filter-3?file=index.ts)

```javascript
import { filter } from "rxjs/operators";
import { from } from "rxjs";

const language$ = from([
  { name: "Java", type: "Orientado a objetos" },
  { name: "Ruby", type: "Multiparadigma" },
  { name: "Haskell", type: "Funcional" },
  { name: "Rust", type: "Multiparadigma" },
]);

language$
  .pipe(filter(({ type }) => type !== "Multiparadigma"))
  .subscribe(console.log);
/* Salida: 
{ name: "Java", type: "Orientado a objetos" },
{ name: "Haskell", type: "Funcional" }
*/
```

### Ejemplos de la documentación oficial

**Emite solo los eventos click cuyo target sea un elemento DIV**

```javascript
import { fromEvent } from "rxjs";
import { filter } from "rxjs/operators";

const clicks = fromEvent(document, "click");
const clicksOnDivs = clicks.pipe(filter((ev) => ev.target.tagName === "DIV"));
clicksOnDivs.subscribe((x) => console.log(x));
```

### Recursos adicionales

[![Source code](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/filtering/assets/icons/source-code.png)](https://github.com/ReactiveX/rxjs/blob/master/src/internal/operators/filter.ts)

[Documentación oficial en inglés](https://rxjs.dev/api/operators/filter)


# first

Emite el primer valor (o el primer valor que cumpla una condición) emitido por el Observable fuente

<details>

<summary>Signatura</summary>

#### Firma

`first<T, D>(predicate?: (value: T, index: number, source: Observable<T>) => boolean, defaultValue?: D): OperatorFunction<T, T | D>`

#### Parámetros

#### Retorna

`OperatorFunction<T, T | D>`: Un Observable del primer elemento que cumpla la condición especificada.

#### Lanza

`EmptyError`: Lanza un `EmptyError` si el Observable se completa sin emitir ninguna notificación `next`.

</details>

## Descripción

Emite únicamente el primer valor. O emite el primer valor que cumpla alguna condición.

![Diagrama de canicas del operador first](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/filtering/assets/images/marble-diagrams/filtering/first.png)

Si se llama sin ningún argumento, `first` emite el primer valor del Observable fuente y se completa. Si se llama con una función `predicate`, `first` emite el valor de la fuente que cumpla la condición especificada. También puede recibir un valor por defecto, que se emite en el caso de que la fuente se complete sin emitir ningún elemento válido. Lanza un error en el caso de que no se encuentre un elemento válido y no se haya proporcionado un `defaultValue` .

## Ejemplos

**Emitir la primera cadena de una secuencia**

[StackBlitz](https://stackblitz.com/edit/rxjs-first-1?file=index.ts)

```javascript
import { first } from "rxjs/operators";
import { from, fromEvent } from "rxjs";

const fruit$ = from(["Cereza", "Fresa", "Arándano"]);

fruit$.pipe(first()).subscribe(console.log);
// Salida: Cereza
```

**Emitir la primera tecla pulsada**

[StackBlitz](https://stackblitz.com/edit/rxjs-rxjs-first-2?file=index.ts)

```typescript
import { first, map } from "rxjs/operators";
import { fromEvent } from "rxjs";

const keyPressed$ = fromEvent<KeyboardEvent>(document, "keydown");

keyPressed$
  .pipe(
    first(),
    map(({ code }) => code)
  )
  .subscribe(console.log);
// Salida: KeyX
```

**Emitir el primer elemento que cumpla una condición**

[StackBlitz](https://stackblitz.com/edit/rxjs-first-3?file=index.ts)

```javascript
import { of } from "rxjs";
import { first } from "rxjs/operators";

const user$ = of(
  { name: "NyaGarcía", age: 23 },
  { name: "zaldih", age: 21 },
  { name: "caballerog", age: 35 }
);

user$.pipe(first(({ age }) => age === 21)).subscribe(console.log);
// Salida: { name: 'zaldih', age: 21 }
```

**Proporcionar un valor por defecto, que será emitido si ningún elemento cumple la condición**

[StackBlitz](https://stackblitz.com/edit/rxjs-first-4?file=index.ts)

```javascript
import { first } from "rxjs/operators";
import { from } from "rxjs";

const language$ = from([
  { name: "Ruby", type: "Multiparadigma" },
  { name: "Haskell", type: "Funcional" },
  { name: "Rust", type: "Multiparadigma" },
]);

language$
  .pipe(
    first(({ type }) => type === "Orientado a objetos", {
      name: "Java",
      type: "Orientado a objetos",
    })
  )
  .subscribe(console.log);
// Salida: { name: "Java", type: "Orientado a objetos" }
```

### Ejemplos de la documentación oficial

**Emitir solo el primer click que ocurra en el DOM**

```javascript
import { fromEvent } from "rxjs";
import { first } from "rxjs/operators";

const clicks = fromEvent(document, "click");
const result = clicks.pipe(first());
result.subscribe((x) => console.log(x));
```

**Emitir el primer click que ocurra en un DIV**

```javascript
import { fromEvent } from "rxjs";
import { first } from "rxjs/operators";

const clicks = fromEvent(document, "click");
const result = clicks.pipe(first((ev) => ev.target.tagName === "DIV"));
result.subscribe((x) => console.log(x));
```

<details>

<summary>Sobrecargas</summary>

#### Firma

`first(predicate?: null, defaultValue?: D): OperatorFunction<T, T | D>`

#### Parameters

#### Retorna

`OperatorFunction<T, T | D>`

#### Firma

`first(predicate: (value: T, index: number, source: Observable<T>) => value is S, defaultValue?: S): OperatorFunction<T, S>`

#### Parameters

#### Retorna

`OperatorFunction<T, S>`

#### Firma

`first(predicate: (value: T, index: number, source: Observable<T>) => boolean, defaultValue?: D): OperatorFunction<T, T | D>`

#### Parameters

#### Retorna

`OperatorFunction<T, T | D>`

</details>

### Recursos adicionales

[![Source code](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/filtering/assets/icons/source-code.png)](https://github.com/ReactiveX/rxjs/blob/master/src/internal/operators/first.ts)

[Documentación oficial en inglés](https://rxjs.dev/api/operators/first)


# ignoreElements

Ignora todos los elementos emitidos por el Observable fuente, propagando únicamente las llamadas a complete o a error

<details>

<summary>Signatura</summary>

#### Firma

`ignoreElements(): OperatorFunction<any, never>`

#### Parámetros

No recibe ningún parámetro

#### Retorna

`OperatorFunction<any, never>`: Un Observable vacío que solo propaga las llamadas `complete` o `error` que haga el Observable fuente.

</details>

## Descripción

![Diagrama de canicas del operador ignoreElements](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/filtering/assets/images/marble-diagrams/filtering/ignoreElements.png)

## Ejemplos

**Ignorar todos los valores del Observable fuente hasta que se complete**

[StackBlitz](https://stackblitz.com/edit/docu-rxjs-ignoreelements?file=index.ts)

```javascript
import { ignoreElements } from "rxjs/operators";
import { of, throwError } from "rxjs";

const hater$ = of(
  "No eres lo suficientemente buena/o",
  "Tu código es una m****a",
  "Nunca vas a conseguirlo",
  "Las mujeres no saben programar"
);

hater$
  .pipe(ignoreElements())
  .subscribe(console.log, console.error, () =>
    console.log("Haters ignorados :)")
  );
// Salida: Haters ignorados :)
```

**Si ocurre un error, será emitido**

[StackBlitz](https://stackblitz.com/edit/docu-rxjs-ignoreelements-2?file=index.ts)

```javascript
import { ignoreElements } from "rxjs/operators";
import { throwError } from "rxjs";

const error$ = throwError("Ha ocurrido un error");

error$
  .pipe(ignoreElements())
  .subscribe(console.log, console.error, () => console.log("Complete"));
// Salida: (error) Ha ocurrido un error
```

### Ejemplo de la documentación oficial

**Ignorar los valores emitidos hasta que el Observable se complete**

```javascript
import { of } from "rxjs";
import { ignoreElements } from "rxjs/operators";

of("you", "talking", "to", "me")
  .pipe(ignoreElements())
  .subscribe(
    (word) => console.log(word),
    (err) => console.log("error:", err),
    () => console.log("the end")
  );
// Salida:
// 'the end'
```

### Recursos adicionales

[![Source code](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/filtering/assets/icons/source-code.png)](https://github.com/ReactiveX/rxjs/blob/master/src/internal/operators/ignoreElements.ts)

[Documentación oficial en inglés](https://rxjs.dev/api/operators/ignoreElements)


# last

Emite el último valor (o el último valor que cumpla una condición) del el Observable fuente

<details>

<summary>Signatura</summary>

#### Firma

`last<T, D>(predicate?: (value: T, index: number, source: Observable<T>) => boolean, defaultValue?: D): OperatorFunction<T, T | D>`

#### Parámetros

#### Retorna

`OperatorFunction<T, T | D>`: Un Observable que emite el último elemento del Observable que cumpla la condición, o un `NoSuchElementException` si no se emite ningún elemento.

#### Lanza

`EmptyError` Propaga un `EmptyError` a la *callback* de error del Observable si este se completa antes de emitir alguna notificación `next`.

`Error` - Se lanza en el caso de que ningún elemento cumple la condición especificada por el Observable fuente.

</details>

## Descripción

Retorna un Observable que emite el último elemento emitido por el Observable fuente. Opcionalmente recibe una función `predicate` como parámetro, en cuyo caso, en lugar de emitir el último elemento del Observable fuente, el Observable resultante emitirá el último elemento del Observable fuente que cumpla la condición especificada.

![Diagrama de canicas del operador last](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/filtering/assets/images/marble-diagrams/filtering/last.png)

## Ejemplos

**Emitir la última cadena de una secuencia**

[StackBlitz](https://stackblitz.com/edit/rxjs-last-1?file=index.ts)

```javascript
import { last } from "rxjs/operators";
import { from, fromEvent } from "rxjs";

const fruit$ = from(["Cereza", "Fresa", "Arándano"]);

fruit$.pipe(last()).subscribe(console.log);
// Salida: Arándano
```

**Emitir el último elemento que cumpla una condición**

[StackBlitz](https://stackblitz.com/edit/rxjs-last-2?file=index.ts)

```javascript
import { of } from "rxjs";
import { last } from "rxjs/operators";

const user$ = of(
  { name: "NyaGarcía", age: 23 },
  { name: "zaldih", age: 21 },
  { name: "caballerog", age: 35 },
  { name: "carla.1003", age: 21 }
);

user$.pipe(last(({ age }) => age === 21)).subscribe(console.log);
// Salida: { name: 'carla.1003', age: 21 }
```

**Proporcionar un valor por defecto, que será emitido si ningún elemento cumple la condición**

[StackBlitz](https://stackblitz.com/edit/rxjs-last-3?file=index.ts)

```javascript
import { last } from "rxjs/operators";
import { from } from "rxjs";

const language$ = from([
  { name: "Haskell", type: "Funcional" },
  { name: "Ruby", type: "Multiparadigma" },
  { name: "Rust", type: "Multiparadigma" },
]);

language$
  .pipe(
    last(({ type }) => type === "Orientado a objetos", {
      name: "Java",
      type: "Orientado a objetos",
    })
  )
  .subscribe(console.log);
// Salida: { name: "Java", type: "Orientado a objetos" }
```

<details>

<summary>Sobrecargas</summary>

#### Firma

`last(predicate?: null, defaultValue?: D): OperatorFunction<T, T | D>`

#### Parámetros

#### Retorna

`OperatorFunction<T, T | D>`

#### Firma

`last(predicate: (value: T, index: number, source: Observable<T>) => value is S, defaultValue?: S): OperatorFunction<T, S>`

#### Parámetros

#### Retorna

`OperatorFunction<T, S>`

#### Firma

`last(predicate: (value: T, index: number, source: Observable<T>) => boolean, defaultValue?: D): OperatorFunction<T, T | D>`

#### Parámetros

#### Retorna

`OperatorFunction<T, T | D>`

</details>

### Recursos adicionales

[![Source code](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/filtering/assets/icons/source-code.png)](https://github.com/ReactiveX/rxjs/blob/master/src/internal/operators/last.ts)

[Documentación oficial en inglés](https://rxjs.dev/api/operators/last)


# sample

Emite la emisión más reciente del Observable fuente cuando un segundo Observable, el notificador, emite un valor

<details>

<summary>Signatura</summary>

#### Firma

`sample<T>(notifier: Observable<any>): MonoTypeOperatorFunction<T>`

#### Parámetros

#### Retorna

`MonoTypeOperatorFunction<T>`: Un Observable que emite el valor más reciente del Observable fuente cuando el Observable `notifier` emite un valor o se completa.

</details>

## Descripción

Es como `sampleTime`, pero toma una muestra del Observable fuente cuando el Observable notificador emite un valor.

![Diagrama de canicas del operador sample](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/filtering/assets/images/marble-diagrams/filtering/sample.png)

Cuando el Observable `notifier` emite un valor o se completa, `sample` toma una muestra del Observable fuente y emite la emisión más reciente desde el último muestreo, a no ser que la fuente no haya emitido nada desde el último muestreo. En cuanto se lleve a cabo la suscripción al Observable resultante, también se realizará la del Observable `notifier`.

## Ejemplos

**Emitir el valor más reciente desde el último muestreo, realizado cuando interval emite (cada 2s)**

[StackBlitz](https://stackblitz.com/edit/rxjs-sample-1?file=index.ts)

```javascript
import { interval } from "rxjs";
import { sample } from "rxjs/operators";

const number$ = interval(1000);

number$.pipe(sample(interval(2000))).subscribe(console.log);
// Salida: 1, 3, 5, 7, 9...
```

**Emitir el valor más reciente desde el último muestreo, realizado cada vez que se pulsa una tecla**

[StackBlitz](https://stackblitz.com/edit/rxjs-sample-2?file=index.ts)

```typescript
import { fromEvent, interval } from "rxjs";
import { sample } from "rxjs/operators";

const number$ = interval(1000);
const key$ = fromEvent<KeyboardEvent>(document, "keydown");

number$
  .pipe(sample(key$))
  .subscribe((n) =>
    console.log(`El último valor emitido tras la última tecla pulsada es: ${n}`)
  );
// Salida: El último valor emitido tras la última tecla pulsada es: n
```

### Ejemplo de la documentación oficial

**Con cada click, realizar un muestreo del temporizador seconds**

```javascript
import { fromEvent, interval } from "rxjs";
import { sample } from "rxjs/operators";

const seconds = interval(1000);
const clicks = fromEvent(document, "click");
const result = seconds.pipe(sample(clicks));
result.subscribe((x) => console.log(x));
```

### Recursos adicionales

[![Source code](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/filtering/assets/icons/source-code.png)](https://github.com/ReactiveX/rxjs/blob/master/src/internal/operators/sample.ts)

[Documentación oficial en inglés](https://rxjs.dev/api/operators/sample)


# sampleTime

Emite la emisión más reciente del Observable fuente en cada periodo de tiempo determinado

<details>

<summary>Signatura</summary>

#### Firma

`sampleTime<T>(period: number, scheduler: SchedulerLike = async): MonoTypeOperatorFunction<T>`

#### Parámetros

#### Retorna

`MonoTypeOperatorFunction<T>`: Un Observable que emite la emisión más reciente del Observable fuente en el intervalo de tiempo especificado.

</details>

## Descripción

Toma una muestra del Observable fuente a intervalos periódicos de tiempo, emitiendo la emisión más reciente en dicho periodo de tiempo.

![Diagrama de canicas del operador sampleTime](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/filtering/assets/images/marble-diagrams/filtering/sampleTime.png)

`sampleTime` emite la emisión más reciente del Observable fuente, desde el último muestreo, a no ser que la fuente no haya emitido nada desde el último muestreo. El muestreo ocurre de forma periódica, cada `period` milisegundos (o la unidad de tiempo definida por el argumento opcional `scheduler`.) El muestreo comienza en cuando se realice la suscripción al Observable resultante.

## Ejemplos

**Emitir el valor más reciente desde el último muestreo, realizado cada 2 segundos**

[StackBlitz](https://stackblitz.com/edit/rxjs-sampletime-1?file=index.ts)

```javascript
import { fromEvent, interval } from "rxjs";
import { sampleTime } from "rxjs/operators";

const number$ = interval(1000);

number$.pipe(sampleTime(2000)).subscribe(console.log);
// Salida: 0, 2, 4, 6, 8...
```

**Emitir la tecla pulsada más reciente desde el último muestreo, realizado cada 2 segundos**

[StackBlitz](https://stackblitz.com/edit/rxjs-sampletime-2?file=index.ts)

```typescript
import { fromEvent } from "rxjs";
import { map, sampleTime } from "rxjs/operators";

const key$ = fromEvent<KeyboardEvent>(document, "keydown");

key$
  .pipe(
    sampleTime(2000),
    map(({ code }) => code)
  )
  .subscribe((code) =>
    console.log(`La tecla pulsada más reciente es: ${code}`)
  );
// Salida: (Pulsar tecla y) (Pulsar tecla x) La tecla pulsada más reciente es: KeyX
```

### Ejemplo de la documentación oficial

**Cada segundo, emitir el click más reciente**

```javascript
import { fromEvent } from "rxjs";
import { sampleTime } from "rxjs/operators";

const clicks = fromEvent(document, "click");
const result = clicks.pipe(sampleTime(1000));
result.subscribe((x) => console.log(x));
```

### Recursos adicionales

[![Source code](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/filtering/assets/icons/source-code.png)](https://github.com/ReactiveX/rxjs/blob/master/src/internal/operators/sampleTime.ts)

* [Documentación oficial en inglés](https://rxjs.dev/api/operators/sampleTime)


# single

Emite si solo existe un único valor que cumpla la condición

<details>

<summary>Signatura</summary>

#### Firma

`single<T>(predicate?: (value: T, index: number, source: Observable<T>) => boolean): MonoTypeOperatorFunction<T>`

#### Parámetros

#### Retorna

`MonoTypeOperatorFunction<T>`: Un Observable que puede emitir un único valor del Observable fuente que cumpla la condición, o `undefined` si ninguno la cumple.

#### Lamza

`EmptyError` Lanza un `EmptyError` si el Observable se completa sin emitir ninguna notificación `next`.

</details>

## Descripción

Es como `first`, pero emite un error si hay más de un valor.

![Diagrama de canicas del operador single](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/filtering/assets/images/marble-diagrams/filtering/single.png)

Retorna un Observable que emite el único valor emitido por el Observable fuente que cumpla la condición especificada, en el caso de que exista dicho valor. Si el Observable fuente emite más de un elemento que cumpla la condición, o no emite ningún elemento, se lanzarán un `IllegalArgumentException` o un `NoSuchElementException` respectivamente.

Si el Observable fuente emite elementos, pero ninguno cumple la condición especificada, se emitirá `undefined`.

## Ejemplos

**Emitir el único elemento que cumpla la condición**

[StackBlitz](https://stackblitz.com/edit/rxjs-single-1?file=index.ts)

```javascript
import { single } from "rxjs/operators";
import { from } from "rxjs";

const language$ = from([
  { name: "Java", type: "Orientado a objetos" },
  { name: "Ruby", type: "Multiparadigma" },
  { name: "Haskell", type: "Funcional" },
]);

language$
  .pipe(single(({ type }) => type === "Multiparadigma"))
  .subscribe(console.log);
// Salida: { name: "Ruby", type: "Multiparadigma" }
```

**Si hay más de un elemento que cumpla la condición, se lanzará un error**

[StackBlitz](https://stackblitz.com/edit/rxjs-single-2?file=index.ts)

```javascript
import { range } from "rxjs";
import { single } from "rxjs/operators";

const number$ = range(1, 5);

number$.pipe(single((n) => n % 2 === 0)).subscribe(console.log, console.error);
// Salida: (error) Sequence contains more than one element
```

**Si no hay ningún elemento que cumpla la condición, se emitirá undefined**

[StackBlitz](https://stackblitz.com/edit/rxjs-single-3?file=index.ts)

```javascript
import { of } from "rxjs";
import { single } from "rxjs/operators";

const user$ = of(
  { name: "NyaGarcía", age: 23 },
  { name: "zaldih", age: 21 },
  { name: "caballerog", age: 35 }
);

user$.pipe(single(({ age }) => age < 18)).subscribe(console.log);
// Salida: undefined
```

### Ejemplos de la documentación oficial

**Emitir 'Error'**

```javascript
import { range } from "rxjs";
import { single } from "rxjs/operators";

const numbers = range(1, 5).pipe(single());
numbers.subscribe(
  (x) => console.log("Nunca se llamará"),
  (e) => console.log("Error")
);
// Salida
// 'Error'
```

**Emitir 'undefined'**

```javascript
import { range } from "rxjs";
import { single } from "rxjs/operators";

const numbers = range(1, 5).pipe(single((x) => x === 10));
numbers.subscribe((x) => console.log(x));
// Salida
// 'undefined'
```

### Recursos adicionales

[![Source code](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/filtering/assets/icons/source-code.png)](https://github.com/ReactiveX/rxjs/blob/master/src/internal/operators/single.ts)

[Documentación oficial en inglés](https://rxjs.dev/api/operators/single)


# skip

Retorna un Observable que se salta las primeras x emisiones del Observable fuente

<details>

<summary>Signatura</summary>

#### Firma

`skip<T>(count: number): MonoTypeOperatorFunction<T>`

#### Parámetros

#### Retorna

`MonoTypeOperatorFunction<T>`: Un Observable que se salta valores emitidos por el Observable fuente.

</details>

## Descripción

`skip` se salta un número determinado por el parámetro `count` de emisiones del Observable fuente, y después continúa emitiendo valores normalmente.

![Diagrama de canicas del operador skip](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/filtering/assets/images/marble-diagrams/filtering/skip.png)

## Ejemplos

**Ignorar los primeros 5 clicks**

[StackBlitz](https://stackblitz.com/edit/rxjs-skip-1?file=index.ts)

```javascript
import { skip } from "rxjs/operators";
import { from, fromEvent } from "rxjs";

const click$ = fromEvent(document, "click");

click$.pipe(skip(5)).subscribe(console.log);
// Salida: ......... ClickEvent {}...
```

**Ignorar el primer elemento**

[StackBlitz](https://stackblitz.com/edit/rxjs-skip-2?file=index.ts)

```javascript
import { skip } from "rxjs/operators";
import { from } from "rxjs";

const language$ = from([
  { name: "Java", type: "Orientado a objetos" },
  { name: "Ruby", type: "Multiparadigma" },
  { name: "Haskell", type: "Funcional" },
]);

language$.pipe(skip(1)).subscribe(console.log);
// Salida: { name: "Ruby", type: "Multiparadigma" }, { name: "Haskell", type: "Funcional" }
```

### Recursos adicionales

[![Source code](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/filtering/assets/icons/source-code.png)](https://github.com/ReactiveX/rxjs/blob/master/src/internal/operators/skip.ts)

[Documentación oficial en inglés](https://rxjs.dev/api/operators/skip)


# skipLast

Saltar las últimas x emisiones del Observable fuente

<details>

<summary>Signatura</summary>

#### Firma

`skipLast<T>(count: number): MonoTypeOperatorFunction<T>`

#### Parámetros

#### Retornar

`MonoTypeOperatorFunction<T>`: Un Observable que se salta los últimos `count` valores emitidos por el Observable fuente.

#### Lanza

`ArgumentOutOfRangeError` Al usar `skipLast(i)`, se lanza un error `ArgumentOutOrRangeError` si `i < 0`.

</details>

## Descripción

Se salta las últimas `count` emisiones del Observable fuente.

![Diagrama de canicas del operador skipLast](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/filtering/assets/images/marble-diagrams/filtering/skipLast.png)

`skipLast` retorna un Observable que acumula una cola de tamaño suficiente para almacenar los primeros `count` valores. Al recibirse más emisiones, se obtienen los valores del principio de la cola y se emiten en el Observable resultante. Esto hace que las emisiones se retrasen.

## Ejemplos

**Saltar los últimos 5 números**

[StackBlitz](https://stackblitz.com/edit/rxjs-skiplast-1?file=index.ts)

```javascript
import { skipLast } from "rxjs/operators";
import { range } from "rxjs";

const number$ = range(1, 10);

number$.pipe(skipLast(5)).subscribe(console.log);
// Salida: 1, 2, 3, 4, 5
```

**Saltar el último valor**

[StackBlitz](https://stackblitz.com/edit/rxjs-skiplast-2?file=index.ts)

```javascript
import { skipLast } from "rxjs/operators";
import { from } from "rxjs";

const language$ = from([
  { name: "Java", type: "Orientado a objetos" },
  { name: "Ruby", type: "Multiparadigma" },
  { name: "Haskell", type: "Funcional" },
]);

language$.pipe(skip(1)).subscribe(console.log);
// Salida: { name: "Ruby", type: "Multiparadigma" }, { name: "Haskell", type: "Funcional" }
```

### Ejemplo de la documentación oficial

**Saltar los 2 últimos valores de un Observable**

```javascript
import { range } from "rxjs";
import { skipLast } from "rxjs/operators";

const many = range(1, 5);
const skipLastTwo = many.pipe(skipLast(2));
skipLastTwo.subscribe((x) => console.log(x));

// Salida:
// 1 2 3
```

### Recursos adicionales

[![Source code](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/filtering/assets/icons/source-code.png)](https://github.com/ReactiveX/rxjs/blob/master/src/internal/operators/skipLast.ts)

[Documentación oficial en inglés](https://rxjs.dev/api/operators/skipLast)


# skipUntil

Retorna un Observable que se salta los valores emitidos por el Observable fuente hasta que un segundo Observable emite un valor

<details>

<summary>Signatura</summary>

#### Firma

`skipUntil<T>(notifier: Observable<any>): MonoTypeOperatorFunction<T>`

#### Parámetros

#### Retorna

`MonoTypeOperatorFunction<T>`: Un Observable que se salta elementos del Observable fuente hasta que el segundo Observable emite un valor. Entonces, comienza a emitir valores normalmente.

</details>

## Descripción

El operador `skipUntil` se salta las emisiones del Observable fuente hasta que el segundo Observable emita un valor. Esto puede ser especialmente útil para gestionar las interacciones del usuario, las respuestas de peticiones http o para esperar a que pasen periodos determinados de tiempo.

![Diagrama de canicas del operador skipUntil](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/filtering/assets/images/marble-diagrams/filtering/skipUntil.png)

Internamente, el operador `skipUntil` se suscribe al Observable recibido por parámetros (conocido como Observable notificador) para poder saber cuándo emite el primer valor. Cuando esto ocurra, el operador cancela la suscripcón al Observable notificador y comienza a emitir los valores del Observable fuente.

Si el Observable notificador se completa o lanza un error sin haber emitido ningún valor, los valores del Observable fuente nunca se emitirán.

## Ejemplos

**Saltar la secuencia de números hasta que se pulse la barra espaciadora**

[StackBlitz](https://stackblitz.com/edit/rxjs-skipuntil-1?file=index.ts)

```typescript
import { filter, map, skipUntil } from "rxjs/operators";
import { fromEvent, interval } from "rxjs";

const number$ = interval(1000);

const key$ = fromEvent<KeyboardEvent>(document, "keydown").pipe(
  map(({ code }) => code),
  filter((code) => code === "Space")
);

number$.pipe(skipUntil(key$)).subscribe(console.log);
// Salida: (4s) (Pulsar barra espaciadora) 4, 5, 6...
```

**Saltar la secuencia de números hasta que pasen 4 segundos**

[StackBlitz](https://stackblitz.com/edit/rxjs-skipuntil-2?file=index.ts)

```javascript
import { skipUntil } from "rxjs/operators";
import { timer, interval } from "rxjs";

const number$ = interval(1000);
const timer$ = timer(4000);

number$.pipe(skipUntil(timer$)).subscribe(console.log);
// Salida: 3, 4, 5, 6, 7, 8...
```

### Ejemplo de la documentación oficial

**Saltar las emisiones del Observable fuente hasta que el usuario haga click**

```javascript
import { interval, fromEvent } from "rxjs";
import { skipUntil } from "rxjs/operators";

const intervalObservable = interval(1000);
const click = fromEvent(document, "click");

const emitAfterClick = intervalObservable.pipe(skipUntil(click));
// Click a los 4.6s. Salida: 5...6...7...8........ o
// Click a los 7.3s. Salida: 8...9...10..11.......
const subscribe = emitAfterClick.subscribe((value) => console.log(value));
```

### Recursos adicionales

[![Source code](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/filtering/assets/icons/source-code.png)](https://github.com/ReactiveX/rxjs/blob/master/src/internal/operators/skipUntil.ts)

[Documentación oficial en inglés](https://rxjs.dev/api/operators/skipUntil)


# skipWhile

Se salta las emisiones del Observable fuente hasta que una condición deje de cumplirse

<details>

<summary>Signatura</summary>

#### Firma

`skipWhile<T>(predicate: (value: T, index: number) => boolean): MonoTypeOperatorFunction<T>`

#### Parámetros

#### Retorna

`MonoTypeOperatorFunction<T>`: Un Observable que comienza a emitir las emisiones del Observable fuente cuando la condición especificada en la función `predicate` retorne `false`.

</details>

## Descripción

Retorna un Observable que se salta los elementos emitidos por el Observable fuente mientras la condición especificada retorne `true`, y que empieza a emitirlos en cuanto la condición deje de cumplirse.

![Diagrama de canicas del operador skipWhile](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/filtering/assets/images/marble-diagrams/filtering/skipWhile.png)

Advertencia: Una vez que la condición no se cumpla, no se volverá a revaluar. Esto quiere decir que si la condición comienza siendo falsa, aunque más adelante sí se cumpla, no tendrá ningún efecto. Este comportamiento se puede apreciar en el segundo ejemplo:

## Ejemplos

**Saltar la secuencia de números mientras sean menores que 3**

[StackBlitz](https://stackblitz.com/edit/rxjs-skipwhile-1?file=index.ts)

```javascript
import { skipWhile } from "rxjs/operators";
import { interval } from "rxjs";

const number$ = interval(1000);

number$.pipe(skipWhile((num) => num < 3)).subscribe(console.log);
// Salida: 3, 4, 5, 6, 7...
```

**Si la condición comienza siendo falsa, no se saltará ningún valor**

La condición no se cumple cuando el Observable comienza a emitir (los números emitidos no son mayores que 3), por lo que, aunque más adelante sí que se cumpla (cuando los números emitidos sean mayores que 3), no se saltará ningún valor. Esto es debido a que la condición nunca vuelve a evaluarse tras devolver `false`.

[StackBlitz](https://stackblitz.com/edit/rxjs-skipwhile-2?file=index.ts)

```javascript
import { skipWhile } from "rxjs/operators";
import { interval } from "rxjs";

const number$ = interval(1000);

number$.pipe(skipWhile((num) => num > 3)).subscribe(console.log);
// Salida: 0, 1, 2, 3, 4, 5, 6, 7...
```

**Saltar los lenguajes mientras sean de tipo Multiparadigma**

[StackBlitz](https://stackblitz.com/edit/rxjs-skipwhile-3?file=index.ts)

```javascript
import { skipWhile } from "rxjs/operators";
import { from } from "rxjs";

const language$ = from([
  { name: "Ruby", type: "Multiparadigma" },
  { name: "Rust", type: "Multiparadigma" },
  { name: "Java", type: "Orientado a objetos" },
  { name: "Scala", type: "Multiparadigma" },
  { name: "Haskell", type: "Funcional" },
]);

language$
  .pipe(skipWhile(({ type }) => type === "Multiparadigma"))
  .subscribe(console.log);
/* Salida:
  { name: "Java", type: "Orientado a objetos" },
  { name: "Scala", type: "Multiparadigma" },
  { name: "Haskell", type: "Funcional" },
*/
```

### Recursos adicionales

[![Source code](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/filtering/assets/icons/source-code.png)](https://github.com/ReactiveX/rxjs/blob/master/src/internal/operators/skipWhile.ts)

[Documentación oficial en inglés](https://rxjs.dev/api/operators/skipWhile)


# take

Emite las primeras x emisiones del Observable fuente

<details>

<summary>Signatura</summary>

#### Firma

`take<T>(count: number): MonoTypeOperatorFunction<T>`

#### Parámetros

#### Retorna

`MonoTypeOperatorFunction<T>`: Un Observable que emite o las primeras `count` emisiones del Observable fuente, o todas las emisiones si el Observable fuente emite menos de `count` valores.

#### Lanza

`ArgumentOutOfRangeError` Cuando se usa `take(i)`, se lanza un Error `ArgumentOutOrRangeError` si `i < 0`.

</details>

## Descripción

Obtiene los primeros `count` valores de la fuente, y se completa.

![Diagrama de canicas del operador take](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/filtering/assets/images/marble-diagrams/filtering/take.png)

`take` retorna un Observable que emite únicamente los primeros `count` valores emitidos por el Observable fuente. Si la fuente emite menos de n valores, entonces se emiten todos los valores. Después, se completa el Observable, independientemente de si la fuente se completa o no.

## Ejemplos

**Emitir las primeras 5 teclas pulsadas**

[StackBlitz](https://stackblitz.com/edit/rxjs-take-1?file=index.ts)

```typescript
import { map, take } from "rxjs/operators";
import { fromEvent } from "rxjs";

const key$ = fromEvent<KeyboardEvent>(document, "keydown");

key$
  .pipe(
    map(({ code }) => code),
    take(5)
  )
  .subscribe(console.log);
// Salida: KeyR, KeyX, KeyJ, KeyS, Space
```

**Emitir los primeros 3 títulos de películas de Studio Ghibli**

[StackBlitz](https://stackblitz.com/edit/rxjs-take-2?file=index.ts)

```javascript
import { ajax } from "rxjs/ajax";
import { map, mergeAll, take } from "rxjs/operators";

const ghibliFilm$ = ajax.getJSON("https://ghibliapi.herokuapp.com/films").pipe(
  mergeAll(),
  map(({ title }) => title)
);

ghibliFilm$.pipe(take(5)).subscribe(console.log);
// Salida: Castle in the Sky, Grave of the Fireflies, My Neighbor Totoro
```

### Ejemplo de la documentación oficial

**Obtener los 5 primeros segundos de un Observable infinito de un intervalo de 1 segundo.**

```javascript
import { interval } from "rxjs";
import { take } from "rxjs/operators";

const intervalCount = interval(1000);
const takeFive = intervalCount.pipe(take(5));
takeFive.subscribe((x) => console.log(x));

// Salida: 0, 1, 2, 3, 4
```

### Recursos adicionales

[![Source code](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/filtering/assets/icons/source-code.png)](https://github.com/ReactiveX/rxjs/blob/master/src/internal/operators/take.ts)

[Documentación oficial en inglés](https://rxjs.dev/api/operators/take)


# takeLast

Emite las últimas x emisiones del Observable fuente

<details>

<summary>Signatura</summary>

#### Firma

`takeLast<T>(count: number): MonoTypeOperatorFunction<T>`

#### Parámetros

#### Retorna

`MonoTypeOperatorFunction<T>`: Un Observable que emite las últimas `count` emisiones del Observable fuente.

#### Lanza

`ArgumentOutOfRangeError` Al usar `takeLast(i)`, se lanza un Error `ArgumentOutOrRangeError` si `i < 0`.

</details>

## Descripción

Almacena los últimos `count` valores, y los emite cuando el Observable fuente se completa.

![Diagrama de canicas del operador takeLast](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/filtering/assets/images/marble-diagrams/filtering/takeLast.png)

`takeLast` retorna un Observable que emite los últimos `count` valores emitidos por el Observable fuente. Si la fuente emite menos de `count` valores, se emitirán todos. Este operador debe esperar a que el Observable fuente se complete para poder emitir los últimos `count` valores en el Observable resultante, ya que, de lo contrario, es imposible saber si el Observable fuente emitirá o no más valores. Por esta razón, todos los valores se emiten de forma síncrona, seguidos de la notificación `complete`.

## Ejemplos

**Emitir el último valor de un Observable**

[StackBlitz](https://stackblitz.com/edit/rxjs-takelast-1?file=index.ts)

```javascript
import { takeLast } from "rxjs/operators";
import { from } from "rxjs";

const language$ = from([
  { name: "Java", type: "Orientado a objetos" },
  { name: "Scala", type: "Multiparadigma" },
  { name: "Haskell", type: "Funcional" },
]);

language$.pipe(takeLast(1)).subscribe(console.log);
// Salida: { name: "Haskell", type: "Funcional" }
```

**Si el Observable fuente emite más de count valores, se emitirán todos**

[StackBlitz](https://stackblitz.com/edit/rxjs-takelast-2?file=index.ts)

```javascript
import { takeLast } from "rxjs/operators";
import { range } from "rxjs";

const range$ = range(0, 5);

range$
  .pipe(takeLast(10))
  .subscribe(console.log, console.error, () => console.log("Completado"));
// Salida: 0, 1, 2, 3, 4
```

**Si el Observable fuente no se completa, no se emitirá ningún valor**

[StackBlitz](https://stackblitz.com/edit/rxjs-takelast-3?file=index.ts)

```javascript
import { takeLast } from "rxjs/operators";
import { interval } from "rxjs";

const number$ = interval(1000);

number$
  .pipe(takeLast(5))
  .subscribe(console.log, console.error, () => console.log("Complete"));
// Salida:
```

### Ejemplo de la documentación oficial

**Emite los últimos 3 valores de un Observable**

```javascript
import { range } from "rxjs";
import { takeLast } from "rxjs/operators";

const many = range(1, 100);
const lastThree = many.pipe(takeLast(3));
lastThree.subscribe((x) => console.log(x));
```

### Recursos adicionales

[![Source code](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/filtering/assets/icons/source-code.png)](https://github.com/ReactiveX/rxjs/blob/master/src/internal/operators/takeLast.ts)

[Documentación oficial en inglés](https://rxjs.dev/api/operators/takeLast)


# takeUntil

Emite los valores emitidos por el Observable fuente hasta que un segundo Observable emita un valor

<details>

<summary>Signatura</summary>

#### Firma

`takeUntil<T>(notifier: Observable<any>): MonoTypeOperatorFunction<T>`

#### Parámetros

#### Retorna

`MonoTypeOperatorFunction<T>`: Un Observable que emite los valores del Observable fuente hasta que el Observable notificador emita un valor.

</details>

## Descripción

Emite valores hasta que un segundo Observable, el notificador, emita un valor. Entonces, se completa.

![Diagrama de canicas del operador takeUntil](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/filtering/assets/images/marble-diagrams/filtering/takeUntil.png)

`takeUntil` se suscribe y comienza a reflejar el Observable fuente. También se encarga de monitorizar un segundo Observable, el notificador que se haya proporcionado. Si el notificador emite un valor, el Observable resultante deja de emitir los valores del Observable fuente y se completa.

Si el notificador no emite ningún valor y se completa, `takeUntil` emitirá todos los valores.

## Ejemplos

**Emitir valores hasta que timer$ emita a los 4 segundos**

[StackBlitz](https://stackblitz.com/edit/rxjs-takeuntil-1?file=index.ts)

```javascript
import { takeUntil } from "rxjs/operators";
import { interval, timer } from "rxjs";

const number$ = interval(1000);
const timer$ = timer(4000);

number$.pipe(takeUntil(timer$)).subscribe(console.log);
// Salida: 0, 1, 2
```

**Emitir valores hasta que se pulse una tecla**

[StackBlitz](https://stackblitz.com/edit/rxjs-takeuntil-2?file=index.ts)

```javascript
import { takeUntil } from "rxjs/operators";
import { interval, fromEvent } from "rxjs";

const number$ = interval(1000);
const key$ = fromEvent(document, "keydown");

number$.pipe(takeUntil(key$)).subscribe(console.log);
// Salida: O, 1, 2, 3, 4 (Pulsar tecla)
```

**Cancelar la ejecución de un Observable con un Sujeto y takeUntil**

Una técnica muy útil para poder cancelar la ejecución de uno o varios Observables es utilizar un Sujeto junto al operador `takeUntil`. De esta manera, no hay que cancelar la suscripción manualmente a todos los Observables que se crean. A continuación, una demostración de esta técnica:

Para cancelar la suscripción a un Observable, se debe almacenar la suscripción a dicho Observable, y llamar al método `unsubscribe`. Esto implica que por cada Observable que se cree, se debe almacenar una Suscripción. Esta forma de cancelar suscripciones es tediosa e imposible de mantener a medida que una aplicación escala.

[StackBlitz](https://stackblitz.com/edit/rxjs-unsubscribe-1?file=index.ts)

```javascript
import { interval, timer } from "rxjs";
import { tap } from "rxjs/operators";

const number$ = interval(1000);

const number$Subscription = number$.subscribe(console.log);

number$Subscription.unsubscribe();
```

Sin embargo, al utilizar el operador `takeUntil`, ya no es necesario almacenar ninguna suscripción. Lo único que hay que hacer es crear un Sujeto, y utilizar `takeUntil` con dicho Sujeto, de tal forma que cuando `stop$` emita un valor, todo Observable que utilice el operador se cancelará.

[StackBlitz](https://stackblitz.com/edit/rxjs-takeuntil-3?file=index.ts)

```javascript
import { takeUntil, tap } from "rxjs/operators";
import { interval, timer, Subject } from "rxjs";

const stop$ = new Subject<void>();

function stop() {
  stop$.next();
  stop$.complete();
}

// Al cabo de 5s, se llamará a la función stop
timer(5000).pipe(tap(_ => stop())).subscribe();

// Will emit numbers until we call the stop function
interval(1000)
  .pipe(takeUntil(stop$))
  .subscribe(console.log);
// Salida: 0, 1, 2, 3, 4 (llamada a stop())
```

### Ejemplo de la documentación oficial

**Emitir una secuencia de números cada segundo, hasta que se haga click**

```javascript
import { fromEvent, interval } from "rxjs";
import { takeUntil } from "rxjs/operators";

const source = interval(1000);
const clicks = fromEvent(document, "click");
const result = source.pipe(takeUntil(clicks));
result.subscribe((x) => console.log(x));
```

### Recursos adicionales

[![Source code](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/filtering/assets/icons/source-code.png)](https://github.com/ReactiveX/rxjs/blob/master/src/internal/operators/takeUntil.ts)

[Documentación oficial en inglés](https://rxjs.dev/api/operators/takeUntil)


# takeWhile

Emite las emisiones del Observable fuente siempre y hasta cuando cumplan la condición especificada. Se completa en cuanto haya un valor que no cumpla la condición

<details>

<summary>Signatura</summary>

#### Firma

`takeWhile<T>(predicate: (value: T, index: number) => boolean, inclusive: boolean = false): MonoTypeOperatorFunction<T>`

#### Parámetros

#### Retorna

`MonoTypeOperatorFunction<T>`: Un Observable que emite los valores del Observable fuente siempre y cuando cada valor cumpla la condición especificada.

</details>

## Descripción

Emite los valores del Observable fuente mientras cumplan la condición especificada. En cuanto un valor no la cumpla, se completa.

![Diagrama de canicas del operador takeWhile](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/filtering/assets/images/marble-diagrams/filtering/takeWhile.png)

`takeWhile` se suscribe al Observable fuente y comienza a reflejarlo. Cada valor que se emita en la fuente, se proporciona a la función `predicate`, que retorna un valor booleano. Este valor indica si el valor cumple o no la condición especificada. El Observable resultante emite los valores del Observable fuente hasta que la condición deje de cumplirse. En ese momento, `takeWhile` deja de emitir los valores del Observable fuente y hace que el Observable resultante se complete.

## Ejemplos

**Emitir números mientras sean menores que 10**

[StackBlitz](https://stackblitz.com/edit/rxjs-takewhile-1?file=index.ts)

```javascript
import { takeWhile } from "rxjs/operators";
import { interval } from "rxjs";

const number$ = interval(1000);

number$
  .pipe(takeWhile((number) => number < 10))
  .subscribe(console.log, console.error, () => console.log("Completado"));
// Salida: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, Completado
```

**Emitir las teclas pulsadas mientras no se pulse la tecla x**

[StackBlitz](https://stackblitz.com/edit/rxjs-takewhile-2?file=index.ts)

```typescript
import { map, takeWhile } from "rxjs/operators";
import { fromEvent } from "rxjs";

const key$ = fromEvent<KeyboardEvent>(document, "keydown");

key$
  .pipe(
    takeWhile(({ code }) => code !== "KeyX"),
    map(({ code }) => code)
  )
  .subscribe(console.log, console.error, () => console.log("Completado"));
// Salida: KeyP, KeyC, KeyM (Pulsar KeyX), Completado
```

**Emitir lenguajes mientras sean de tipo Multiparadigma**

[StackBlitz](https://stackblitz.com/edit/rxjs-takewhile-3?file=index.ts)

```javascript
import { from } from "rxjs";
import { takeWhile } from "rxjs/operators";

const language$ = from([
  { name: "Ruby", type: "Multiparadigma" },
  { name: "Rust", type: "Multiparadigma" },
  { name: "Java", type: "Orientado a objetos" },
  { name: "Scala", type: "Multiparadigma" },
  { name: "Haskell", type: "Funcional" },
]);

language$
  .pipe(takeWhile(({ type }) => type === "Multiparadigma"))
  .subscribe(console.log);
// Salida: { name: "Ruby", type: "Multiparadigma" }, { name: "Rust", type: "Multiparadigma" }
```

**Si se proporciona el valor true como segundo argumento (parámetro inclusive), el primer elemento que no cumpla la condición también se emite**

[StackBlitz](https://stackblitz.com/edit/rxjs-takewhile-4?file=index.ts)

```javascript
import { from } from "rxjs";
import { takeWhile } from "rxjs/operators";

const programmingLanguage$ = from([
  { name: "Simula", type: "Object-oriented" },
  { name: "Java", type: "Object-oriented" },
  { name: "Wolfram", type: "Declarative" },
  { name: "Ruby", type: "Multiparadigm" },
]);

// Si se proporciona el valor true como segundo argumento (parámetro inclusive), el primer elemento que no cumpla la condición también se emite
programmingLanguage$
  .pipe(takeWhile(({ type }) => type === "Object-oriented", true))
  .subscribe(console.log);
// Salida: { name: "Simula", type: "Object-oriented" }, { name: "Java", type: "Object-oriented" }, { name: "Wolfram", type: "Declarative" }
```

### Ejemplo de la documentación oficial

**Emite los eventos click mientras su propiedad clientX sea mayor a 200**

```javascript
import { fromEvent } from "rxjs";
import { takeWhile } from "rxjs/operators";

const clicks = fromEvent(document, "click");
const result = clicks.pipe(takeWhile((ev) => ev.clientX > 200));
result.subscribe((x) => console.log(x));
```

<details>

<summary>Sobrecargas</summary>

#### Firma

`takeWhile(predicate: (value: T, index: number) => value is S): OperatorFunction<T, S>`

#### Parámetros

#### Retorna

`OperatorFunction<T, S>`

#### Firma

`takeWhile(predicate: (value: T, index: number) => value is S, inclusive: false): OperatorFunction<T, S>`

#### Parámetros

#### Retorna

`OperatorFunction<T, S>`

#### Firma

`takeWhile(predicate: (value: T, index: number) => boolean, inclusive?: boolean): MonoTypeOperatorFunction<T>`

#### Parámetros

#### Retorna

`MonoTypeOperatorFunction<T>`

</details>

### Recursos adicionales

[![Source code](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/filtering/assets/icons/source-code.png)](https://github.com/ReactiveX/rxjs/blob/master/src/internal/operators/takeWhile.ts)

[Documentación oficial en inglés](https://rxjs.dev/api/operators/takeWhile)


# throttle

Emite un valor del Observable fuente e ignora las emisiones siguientes durante un tiempo determinado por un segundo Observable. Después, repite el proceso

<details>

<summary>Signatura</summary>

#### Firma

`throttle<T>(durationSelector: (value: T) => SubscribableOrPromise<any>, config: ThrottleConfig = defaultThrottleConfig): MonoTypeOperatorFunction<T>`

#### Parámetros

#### Retorna

`MonoTypeOperatorFunction<T>`: Un Observable que lleva a cabo la acción reguladora para limitar la velocidad de emisión de la fuente.

</details>

## Descripción

Es como `throttleTime`, pero la duración del silenciamiento está determinada por un segundo Observable.

![Diagrama de canicas del operador throttle](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/filtering/assets/images/marble-diagrams/filtering/throttle.png)

`throttle` emite los valores del Observable fuente mientras su temporizador interno esté deshabilitado, e ignora dichos valores mientras el temporizador esté habilitado. Inicialmente, el temporizador está deshabilitado. En cuanto se reciba el primer valor de la fuente, esta se reenvía al Observable resultante y se habilita el temporizador mediante una llamada a la función `durationSelector` con el valor emitido por la fuente. Entonces, la función retorna el Observable de 'duración'. Cuando el Observable de duración emita un valor o se complete, el temporizador se deshabilita, y se repite el proceso para la siguiente emisión del Observable fuente.

## Ejemplos

**Emitir la tecla pulsada, ignorar todos los valores siguientes durante 2 segundos, y repetir**

[StackBlitz](https://stackblitz.com/edit/rxjs-throttle-2?file=index.ts)

```typescript
import { throttle } from "rxjs/operators";
import { fromEvent, interval } from "rxjs";

const key$ = fromEvent<KeyboardEvent>(document, "keydown");

key$
  .pipe(throttle(() => interval(2000)))
  .subscribe(({ code }) => console.log(code));
// Salida: KeyX (2s) KeyO...
```

**Emitir un valor, ignorar todos los valores durante 2 segundos, y repetir**

[StackBlitz](https://stackblitz.com/edit/rxjs-throttle-3?file=index.ts)

```javascript
import { map, throttle } from "rxjs/operators";
import { interval, zip, from } from "rxjs";

// El Observable language$ emite un lenguaje cada segundo
const language$ = zip(
  from(["JavaScript", "TypeScript", "Java", "C#", "Go", "Ruby"]),
  interval(1000)
).pipe(map(([language]) => language));

language$.pipe(throttle(() => interval(2000))).subscribe(console.log);
// Salida: JavaScript, C#
```

### Ejemplo de la documentación oficial

**Emitir como mucho un click por segundo**

```javascript
import { fromEvent } from "rxjs";
import { throttle } from "rxjs/operators";

const clicks = fromEvent(document, "click");
const result = clicks.pipe(throttle((ev) => interval(1000)));
result.subscribe((x) => console.log(x));
```

### Recursos adicionales

[![Source code](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/filtering/assets/icons/source-code.png)](https://github.com/ReactiveX/rxjs/blob/master/src/internal/operators/throttle.ts)

[Documentación oficial en inglés](https://rxjs.dev/api/operators/throttle)


# throttleTime

Emite un valor del Observable fuente e ignora las emisiones siguientes durante un periodo de tiempo determinado. Después, repite el proceso

<details>

<summary>Signatura</summary>

#### Firma

`throttleTime<T>(duration: number, scheduler: SchedulerLike = async, config: ThrottleConfig = defaultThrottleConfig): MonoTypeOperatorFunction<T>`

#### Parámetros

#### Retorna

`MonoTypeOperatorFunction<T>`: Un Observable that performs the throttle operation to limit the rate of emissions from the source.

</details>

## Descripción

Emite un valor, ignorando las siguientes emisiones durante `duration` milisegundos.

![Diagrama de canicas del operador throttleTime](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/filtering/assets/images/marble-diagrams/filtering/throttleTime.png)

throttleTime emite los valores del Observable fuente mientras su temporizador interno está deshabilitado, y los ignora mientras su temporizador está habilitado. Inicialmente, el temporizador está deshablitado. En cuanto se recibe el primer valor de la fuente, este se emite en el Observable resultante y se habilita e temporizador. Tras `duration` milisegundos (o la unidad temporal determinada internamente por el planificador opcional) se deshabilita el temporizador y se repite el proceso para el siguiente valor de la fuente. Opcionalmente, recibe un SchedulerLike para gestionar los temporizadores.

## Ejemplos

**Emitir la tecla pulsada, ignorar todos los valores siguientes durante 2 segundos, y repetir**

[StackBlitz](https://stackblitz.com/edit/rxjs-throttletime-1?file=index.ts)

```typescript
import { throttleTime } from "rxjs/operators";
import { fromEvent } from "rxjs";

const key$ = fromEvent<KeyboardEvent>(document, "keydown");

key$.pipe(throttleTime(2000)).subscribe(({ code }) => console.log(code));
// Salida: KeyX (2s) KeyO...
```

**Emitir un valor, ignorar todos los valores durante 2 segundos, y repetir**

[StackBlitz](https://stackblitz.com/edit/rxjs-throttletime-2?file=index.ts)

```javascript
import { map, throttleTime } from "rxjs/operators";
import { interval, zip, from } from "rxjs";

// El Observable fruit$ emite una fruta cada segundo
const fruit$ = zip(
  from(["Fresa", "Cereza", "Arándano", "Mora", "Frambuesa", "Grosella"]),
  interval(1000)
).pipe(map(([fruit]) => fruit));

fruit$.pipe(throttleTime(2000)).subscribe(console.log);
// Salida: Fresa, Mora
```

### Ejemplos de la documentación oficial

**Emite como mucho un click por segundo**

```javascript
import { fromEvent } from "rxjs";
import { throttleTime } from "rxjs/operators";

const clicks = fromEvent(document, "click");
const result = clicks.pipe(throttleTime(1000));
result.subscribe((x) => console.log(x));
```

**Doble Click**

Emitir clicks que ocurran en los 400ms siguientes al click previo. De esta manera, se detecta el doble click. Hace uso del parámetro de configuración `trailing`.

```javascript
import { fromEvent, asyncScheduler } from "rxjs";
import { throttleTime, withLatestFrom } from "rxjs/operators";

// defaultThottleConfig = { leading: true, trailing: false }
const throttleConfig = {
  leading: false,
  trailing: true,
};

const click = fromEvent(document, "click");
const doubleClick = click.pipe(
  throttleTime(400, asyncScheduler, throttleConfig)
);

doubleClick.subscribe((throttleValue: Event) => {
  console.log(`Doble-click! Timestamp: ${throttleValue.timeStamp}`);
});
```

Si se habilita el parámetro `leading` en este ejemplo, la salida sería el primer click y el doble click, pero se restringiría cualquier click adicional en un periodo de 400ms.

### Recursos adicionales

[![Source code](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/filtering/assets/icons/source-code.png)](https://github.com/ReactiveX/rxjs/blob/master/src/internal/operators/throttleTime.ts)

[Documentación oficial en inglés](https://rxjs.dev/api/operators/throttleTime)


# Matemáticos y Agregación

* [count](/operadores/mathematical-aggregate/count)
* [max](/operadores/mathematical-aggregate/max)
* [min](/operadores/mathematical-aggregate/min)
* [reduce](/operadores/mathematical-aggregate/reduce)


# count

Cuenta el número de emisiones de la fuente y emite el resultado cuando la fuente se completa

<details>

<summary>Signatura</summary>

#### Firma

`count<T>(predicate?: (value: T, index: number, source: Observable<T>) => boolean): OperatorFunction<T, number>`

#### Parámetros

#### Retorna

`OperatorFunction<T, number>`: Un Observable de un solo valor que representa el número de elementos contados.

</details>

## Descripción

Indica cuántos valores se han emitido cuando la fuente se completa.

![Diagrma de cancias del operador count](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/mathematical-aggregate/assets/images/marble-diagrams/mathematical-aggregate/count.png)

`count` transforma un Observable que emite valores en un Observable que emite un solo valor que representa el número de valores emitidos por el Observable fuente. Si el Observable fuente finaliza con un error, `count` enviará la notificación de error sin emitir un valor. Si el Observable fuente no llega a finalizar en ningún momento, `count` no emitirá ningún valor ni finalizará.

Este operador recibe una función opcional `predicate` como argumento, en cuyo caso la emisión representará el número de emisiones que cumplan la función booleana.

## Ejemplos

**Contar el número de emisiones**

[StackBlitz](https://stackblitz.com/edit/rxjs-count-1?file=index.ts)

```javascript
import { range } from "rxjs";
import { count } from "rxjs/operators";

const number$ = range(1, 4);

// Contar el número de emisiones
number$.pipe(count()).subscribe(console.log);
// Salida: 4
```

**Contar el número de teclas pulsadas en 5 segundos**

[StackBlitz](https://stackblitz.com/edit/rxjs-count-2?file=index.ts)

```typescript
import { fromEvent, interval } from "rxjs";
import { count, takeUntil } from "rxjs/operators";

const key$ = fromEvent<KeyboardEvent>(document, "keydown").pipe(
  takeUntil(interval(5000))
);

key$.pipe(count()).subscribe(console.log);
// Salida: (pulsar 5 teclas) 5
```

**Si la fuente no finaliza, count nunca emitirá ni se completará**

[StackBlitz](https://stackblitz.com/edit/rxjs-count-3?file=index.ts)

```javascript
const infiniteNumber$ = interval(1000);

infiniteNumber$.pipe(count()).subscribe(console.log);
// Salida:
```

**Contar las peticiones realizadas con éxito**

[StackBlitz](https://stackblitz.com/edit/rxjs-count-4?file=index.ts)

```javascript
import { of } from "rxjs";
import { ajax } from "rxjs/ajax";
import { concatMap, count } from "rxjs/operators";

const pokemonId$ = of(1, 5, 3);

function getPokemon(id: number) {
  return ajax(`https://pokeapi.co/api/v2/pokemon/${id}`);
}

// Contar las peticiones realizadas con éxito
pokemonId$
  .pipe(
    concatMap((id) => getPokemon(id)),
    count(({ status }) => status === 200)
  )
  .subscribe(console.log);
// Salida: 3
```

**Si ocurre un error, `count` no emitirá nada**

[StackBlitz](https://stackblitz.com/edit/rxjs-count-5?file=index.ts)

```javascript
import { of } from "rxjs";
import { ajax } from "rxjs/ajax";
import { concatMap, count } from "rxjs/operators";

// Al no existir el Pokémon con id -3, hacer la petición provocará un error
const pokemonId$ = of(1, 5, -3);

function getPokemon(id: number) {
  return ajax(`https://pokeapi.co/api/v2/pokemon/${id}`);
}

pokemonId$
  .pipe(
    concatMap((id) => getPokemon(id)),
    count(({ status }) => status === 200)
  )
  .subscribe(console.log, console.error);
// Salida:
```

**Gestionar el error para que count cuente el número de peticiones realizadas con éxito**

[StackBlitz](https://stackblitz.com/edit/rxjs-count-6?file=index.ts)

```javascript
import { of } from "rxjs";
import { ajax } from "rxjs/ajax";
import { catchError, concatMap, count } from "rxjs/operators";

// Al no existir el Pokémon con id -3, hacer la petición provocará un error
const pokemonId$ = of(1, 5, -3);

function getPokemon(id: number) {
  return ajax(`https://pokeapi.co/api/v2/pokemon/${id}`).pipe(
    catchError((err) => of(err))
  );
}

pokemonId$
  .pipe(
    concatMap((id) => getPokemon(id)),
    count(({ status }) => status === 200)
  )
  .subscribe(console.log, console.error);
// Salida: 2
```

### Ejemplos de la documentación oficial

**Contar cuántos segundos pasan desde el primer click**

```javascript
import { fromEvent, interval } from "rxjs";
import { count, takeUntil } from "rxjs/operators";

const seconds = interval(1000);
const clicks = fromEvent(document, "click");
const secondsBeforeClick = seconds.pipe(takeUntil(clicks));
const result = secondsBeforeClick.pipe(count());
result.subscribe((x) => console.log(x));
```

**Contar cuántos números impares hay entre 1 y 7**

```javascript
import { range } from "rxjs";
import { count } from "rxjs/operators";

const numbers = range(1, 7);
const result = numbers.pipe(count((i) => i % 2 === 1));
result.subscribe((x) => console.log(x));
// Resulta en:
// 4
```

### Recursos adicionales

[![Source code](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/mathematical-aggregate/assets/icons/source-code.png)](https://github.com/ReactiveX/rxjs/blob/master/src/internal/operators/count.ts)

[Documentación oficial en inglés](https://rxjs.dev/api/operators/count)


# max

Emite el elemento de mayor valor

<details>

<summary>Signatura</summary>

#### Firma

`max<T>(comparer?: (x: T, y: T) => number): MonoTypeOperatorFunction<T>`

#### Parámetros

#### Retorna

`MonoTypeOperatorFunction<T>`: Un Observable que emite el elemento de mayor valor.

</details>

## Descripción

El operador `max` opera con Observables que emiten valores numéricos (o elementos que se puedan comparar mediante la función de comparación proporcionada), emitiendo un solo valor cuando el Observable fuente se completa: el elemento de mayor valor.

![Diagrama de canicas del operador max](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/mathematical-aggregate/assets/images/marble-diagrams/mathematical-aggregate/max.png)

## Ejemplos

**Obtener el valor máximo de una serie de números**

[StackBlitz](https://stackblitz.com/edit/rxjs-max-1?file=index.ts)

```javascript
import { of } from "rxjs";
import { max } from "rxjs/operators";

const number$ = of(4, 7, 2, 10, 8, 9);

number$.pipe(max()).subscribe(console.log);
// Salida: 10
```

**Utilizar una función de comparación para obtener la cadena más larga**

[StackBlitz](https://stackblitz.com/edit/rxjs-max-2?file=index.ts)

```javascript
import { of } from "rxjs";
import { max } from "rxjs/operators";

const fruit$ = of("Cereza", "Arándano", "Fresa");

// Utilizar una función de comparación para obtener la cadena más larga
fruit$.pipe(max((a, b) => a.length - b.length)).subscribe(console.log);
// Salida: Arándano
```

**Utilizar una función de comparación para comparar objetos anidados y obtener el de mayor valor**

[StackBlitz](https://stackblitz.com/edit/rxjs-max-3?file=index.ts)

```javascript
import { of } from "rxjs";
import { map, max } from "rxjs/operators";

const githubUser$ = of(
  { name: "zaldih", stats: { repositories: 23 } },
  { name: "NyaGarcia", stats: { repositories: 30 } },
  { name: "caballerog", stats: { repositories: 89 } },
  { name: "tonivj5", stats: { repositories: 51 } }
);

githubUser$
  .pipe(
    max((a, b) => a.stats.repositories - b.stats.repositories),
    map(({ name }) => name)
  )
  .subscribe(console.log);
// Salida: caballerog
```

### Ejemplos de la documentación oficial

**Obtener el mayor valor de una serie de números**

```javascript
import { of } from "rxjs";
import { max } from "rxjs/operators";

of(5, 4, 7, 2, 8)
  .pipe(max())
  .subscribe((x) => console.log(x)); // -> 8
```

**Utilizar una función de comparación para obtener el elemento de mayor valor**

```javascript
    import { of } from 'rxjs';
    import { max } from 'rxjs/operators';

    interface Person {
      age: number,
      name: string
    }
    of<Person>(
      {age: 7, name: 'Foo'},
      {age: 5, name: 'Bar'},
      {age: 9, name: 'Beer'},
    ).pipe(
      max<Person>((a: Person, b: Person) => a.age < b.age ? -1 : 1),
    )
    .subscribe((x: Person) => console.log(x.name)); // -> 'Beer'
```

### Recursos adicionales

[![Source code](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/mathematical-aggregate/assets/icons/source-code.png)](https://github.com/ReactiveX/rxjs/blob/master/src/internal/operators/max.ts)

[Documentación oficial en inglés](https://rxjs.dev/api/operators/max)


# min

Emite el elemento de menor valor

<details>

<summary>Signatura</summary>

#### Firma

`min<T>(comparer?: (x: T, y: T) => number): MonoTypeOperatorFunction<T>`

#### Parámetros

#### Retorna

`MonoTypeOperatorFunction<T>`: Un Observable que emite el elemento de menor valor.

</details>

## Descripción

El operador `max` opera con Observables que emiten valores numéricos (o elementos que se puedan comparar mediante la función de comparación proporcionada), emitiendo un solo valor cuando el Observable fuente se completa: el elemento de menor valor.

![Diagrama de canicas del operador min](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/mathematical-aggregate/assets/images/marble-diagrams/mathematical-aggregate/min.png)

## Ejemplos

**Obtener el valor máximo de una serie de números**

[StackBlitz](https://stackblitz.com/edit/rxjs-min-1?file=index.ts)

```javascript
import { of } from "rxjs";
import { min } from "rxjs/operators";

const number$ = of(4, 7, 2, 10, 8, 9);

number$.pipe(min()).subscribe(console.log);
// Salida: 2
```

**Utilizar una función de comparación para obtener la cadena más corta**

[StackBlitz](https://stackblitz.com/edit/rxjs-min-2?file=index.ts)

```javascript
import { of } from "rxjs";
import { min } from "rxjs/operators";

const fruit$ = of("Cereza", "Arándano", "Fresa");

// Utilizar una función de comparación para obtener la cadena más corta
fruit$.pipe(min((a, b) => a.length - b.length)).subscribe(console.log);
// Salida: Fresa
```

**Utilizar una función de comparación para comparar objetos anidados y obtener el de menor valor**

[StackBlitz](https://stackblitz.com/edit/rxjs-min-3?file=index.ts)

```javascript
import { of } from "rxjs";
import { map, min } from "rxjs/operators";

const githubUser$ = of(
  { name: "zaldih", stats: { repositories: 23 } },
  { name: "NyaGarcia", stats: { repositories: 30 } },
  { name: "caballerog", stats: { repositories: 89 } },
  { name: "tonivj5", stats: { repositories: 51 } }
);

githubUser$
  .pipe(
    min((a, b) => a.stats.repositories - b.stats.repositories),
    map(({ name }) => name)
  )
  .subscribe(console.log);
// Salida: zaldih
```

### Ejemplos de la documentación oficial

**Obtener el mayor valor de una serie de números**

```javascript
import { of } from "rxjs";
import { min } from "rxjs/operators";

of(5, 4, 7, 2, 8)
  .pipe(min())
  .subscribe((x) => console.log(x)); // -> 2
```

**Utilizar una función de comparación para obtener el elemento de menor valor**

```javascript
    import { of } from 'rxjs';
    import { min } from 'rxjs/operators';

    interface Person {
      age: number,
      name: string
    }
    of<Person>(
      {age: 7, name: 'Foo'},
      {age: 5, name: 'Bar'},
      {age: 9, name: 'Beer'},
    ).pipe(
      min<Person>( (a: Person, b: Person) => a.age < b.age ? -1 : 1),
    )
    .subscribe((x: Person) => console.log(x.name)); // -> 'Bar'
```

### Recursos adicionales

[![Source code](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/mathematical-aggregate/assets/icons/source-code.png)](https://github.com/ReactiveX/rxjs/blob/master/src/internal/operators/min.ts)

[Documentación oficial en inglés](https://rxjs.dev/api/operators/min)


# reduce

Aplica una función acumuladora al Observable fuente y retorna el resultado acumulado una vez se completa la fuente

💡 Si se necesita el valor acumulado en cada emisión, se puede utilizar [scan](https://github.com/puntotech/rxjs-docu/blob/master/operators/transformation/scan/README.md)

<details>

<summary>Signatura</summary>

#### Firma

`reduce<T, R>(accumulator: (acc: T | R, value: T, index?: number) => T | R, seed?: T | R): OperatorFunction<T, T | R>`

#### Parámetros

#### Retorna

`OperatorFunction<T, T | R>`: Un Observable que emite un solo valor, resutante de haber acumulado los valores emitidos por el Observable fuente.

</details>

## Descripción

Combina todos los valores emitidos por la fuente mediante una función acumuladora, que indica cómo unir cada nuevo valor al valor acumulado.

![Diagrama de canicas del operador reduce](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/mathematical-aggregate/assets/images/marble-diagrams/mathematical-aggregate)

Al igual que `Array.prototype.reduce()`, el operador `reduce` aplica una función acumuladora a cada valor emitido por el Observable fuente para reducirlos a un único valor, que se emite en el Observable resultante. Se debe tener en cuenta que `reduce` solo emite un valor, cuando el Observable fuente se completa. Es equivalente a utilizar el operador `scan` junto al operador `last`.

Retorna un Observable que aplica la función acumuladora especificada a cada elemento emitido por el Observable fuente. Si se especifica un valor `seed`, se utilizará dicho valor como valor inicial para la acumulación inicial. Si no se especificara un valor inicial, se utilizará el primer elemento de la fuente como tal.

## Ejemplos

### Ejemplos de la documentación oficial

**Contar el número de eventos click que ocurran en 5 segundos**

```javascript
import { fromEvent, interval } from "rxjs";
import { reduce, takeUntil, mapTo } from "rxjs/operators";

const clicksInFiveSeconds = fromEvent(document, "click").pipe(
  takeUntil(interval(5000))
);
const ones = clicksInFiveSeconds.pipe(mapTo(1));
const seed = 0;
const count = ones.pipe(reduce((acc, one) => acc + one, seed));
count.subscribe((x) => console.log(x));
```

<details>

<summary>Sobrecargas</summary>

#### Firma

`reduce(accumulator: (acc: R, value: T, index: number) => R, seed: R): OperatorFunction<T, R>`

#### Parámetros

#### Retorna

`OperatorFunction<T, R>`

#### Firma

`reduce(accumulator: (acc: T, value: T, index: number) => T, seed?: T): MonoTypeOperatorFunction<T>`

#### Parámetros

#### Retorna

`MonoTypeOperatorFunction<T>`

#### Firma

`reduce(accumulator: (acc: R, value: T, index: number) => R): OperatorFunction<T, R>`

#### Parámetros

#### Retorna

`OperatorFunction<T, R>`

</details>

### Recursos adicionales

[![Source code](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/mathematical-aggregate/assets/icons/source-code.png)](https://github.com/ReactiveX/rxjs/blob/master/src/internal/operators/reduce.ts)

[Documentación oficial en inglés](https://rxjs.dev/api/operators/reduce)


# Multidifusión

* [connect](/operadores/multicasting/connect)
* [share](/operadores/multicasting/share)
* [shareReplay](/operadores/multicasting/sharereplay)

## Operadores obsoletos

* [multicast](/operadores/multicasting/multicast) (obsoleto)
* [publish](/operadores/multicasting/publish) (obsoleto)
* [publishBehavior](/operadores/multicasting/publishbehavior) (obsoleto)
* [publishLast](/operadores/multicasting/publishlast) (obsoleto)
* [publishReplay](/operadores/multicasting/publishreplay) (obsoleto)
* [refCount](/operadores/multicasting/refcount) (obsoleto)


# connect

Crea un Observable al multidifundir el Observable fuente dentro de una función que permite al desarrollador definir el uso del multicast tras la conexión

<details>

<summary>Signatura</summary>

#### Firma

`connect<T, O extends ObservableInput<unknown>>(selector: (shared: Observable<T>) => O, config: ConnectConfig<T> = DEFAULT_CONFIG): OperatorFunction<T, ObservedValueOf<O>>`

#### Parámetros

#### Retorna

`OperatorFunction<T, ObservedValueOf<O>>`

</details>

## Descripción

Este operador es especialmente útil si el Observable fuente que se quiere multidifundir es síncrono o asíncrono. Ahí radica la diferencia con el operador share, que, en el caso de las fuentes totalmente síncronas, fallará al intentar compartir una sola suscripción con varios consumidores, ya que para el momento en el que la suscripción al resultado de share haya retornado, si la fuente es síncrona en su referencia interna, el recuento de referencias saltará de 0 a 1, de vuelta a 0 y se reiniciará.

Para utilizar `connect`, hay que proporcionar una función `selector` que nos dará un Observable multidifundido (que todavía no ha sido conectado). Entonces, se utiliza ese Observable multidifundido para crear un Observable resultante que, al suscribirnos a él, se encargará de configurar el *multicast*. Esto se suele conseguir, aunque no siempre, con merge.

Téngase en cuenta que el utilizar el operador takeUntil dentro del `selector` de `connect`, puede ser síntoma de que en realidad haya que utilizar el operador takeWhile.

Cuando se lleva a cabo la suscripción al resultado de `connect`, la función `selector` será llamada. Cuando la función `selector` retorne, el Observable que retorne será suscrito, y *entonces* será cuando el *multicast* se conectará a la fuente.

## Ejemplo

Compartiendo un Observable completamente síncrono

```
import { of, tap, connect, merge, map, filter } from 'rxjs';

const source$ = of(1, 2, 3, 4, 5).pipe(
  tap({
    subscribe: () => console.log('suscripción empezada'),
    next: n => console.log(`la fuente ha emitido ${ n }`)
  })
);

source$.pipe(
  // Aquí estamos uniendo 3 subscriptions a `shared$`.
  connect(shared$ => merge(
    shared$.pipe(map(n => `all ${ n }`)),
    shared$.pipe(filter(n => n % 2 === 0), map(n => `par ${ n }`)),
    shared$.pipe(filter(n => n % 2 === 1), map(n => `impar ${ n }`))
  ))
)
.subscribe(console.log);

// Salida esperada: (notice only one subscription)
'suscripción empezada'
'la fuente ha emitido 1'
'all 1'
'impar 1'
'la fuente ha emitido 2'
'all 2'
'par 2'
'la fuente ha emitido 3'
'all 3'
'impar 3'
'la fuente ha emitido 4'
'all 4'
'par 4'
'la fuente ha emitido 5'
'all 5'
'impar 5'
```


# multicast

Comparte el Observable fuente utilizando un Sujeto

<details>

<summary>Signatura</summary>

#### Firma

`multicast<T, R>(subjectOrSubjectFactory: Subject<T> | (() => Subject<T>), selector?: (source: Observable<T>) => Observable<R>): OperatorFunction<T, R>`

#### Parámetros

#### Retorna

`OperatorFunction<T, R>`: Un Observable que emite el resultado de invocar el selector sobre las emisiones de un ConnectableObservable, que comparte una sola suscripción al flujo subyacente.

</details>

## Descripción

Retorna un Observable que emite el resultado de invocar el selector especificado sobre los elementos emitidos por un ConnectableObservable, que comparte una sola suscripción al flujo subyacente

![Diagrama de canicas del operador multicast](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/multicasting/assets/images/marble-diagrams/multicasting/multicast.png)

## Ejemplos

**Compartir el Observable fuente utilizando un Sujeto normal**

Dado que la fuente es compartida, aunque haya varios observadores (suscriptores), el efecto colateral se ejecuta una sola vez.

[StackBlitz](https://stackblitz.com/edit/docu-rxjs-multicast?file=index.ts)

```javascript
import { ConnectableObservable, interval, Subject, timer } from "rxjs";
import { take, tap, multicast } from "rxjs/operators";

const number$ = interval(1000).pipe(take(2));

// Al usar multicast, estamos convirtiendo el Observable number$ en un Observable caliente
const multicasted$ = number$.pipe(
  tap(() =>
    console.log(
      "Observable caliente, efecto secundario se ejecuta una sola vez"
    )
  ),
  multicast(() => new Subject())
) as ConnectableObservable<number>;

// number$ no comenzará a emitir valores hasta que no llamemos al método connect()
timer(3000)
  .pipe(tap(() => console.log("Conectado")))
  .subscribe(() => multicasted$.connect());

multicasted$.subscribe(val => console.log(`Observador 1: ${val}`));
multicasted$.subscribe(val => console.log(`Observador 2: ${val}`));

/* Salida:
(3s)
Conectado
(1s)
Observable caliente, efecto secundario se ejecuta una sola vez,
Observador 1: 0,
Observador 2: 0,
(1s)
Observable caliente, efecto secundario se ejecuta una sola vez,
Observador 1: 1,
Observador 2: 1,
*/
```

**Compartir el Observable fuente utilizando un Sujeto normal, con observadores tardíos**

Si se utiliza un Sujeto normal, los observadores que se suscriban más tarde no recibirán los valores que ya se hayan emitido.

[StackBlitz](https://stackblitz.com/edit/docu-rxjs-multicast-2?file=index.ts)

```javascript
import { ConnectableObservable, interval, Subject, timer } from 'rxjs';
import { take, tap, multicast } from 'rxjs/operators';

const number$ = interval(1000).pipe(take(2));

const multicasted$ = number$.pipe(
  tap(() =>
    console.log(
      'Observable caliente, efecto secundario se ejecuta una sola vez'
    )
  ),
  multicast(() => new Subject())
) as ConnectableObservable<number>;

timer(3000)
  .pipe(tap(() => console.log('Conectado')))
  .subscribe(() => multicasted$.connect());

multicasted$.subscribe((val) => console.log(`Observador 1: ${val}`));

// Si el observador se suscribe más tarde, no recibirá los valores que ya se hayan emitido
timer(5000)
  .pipe(
    tap(() =>
      multicasted$.subscribe((val) => console.log(`Observador tardío: ${val}`))
    )
  )
  .subscribe();

/* Salida:
(3s)
Conectado
(1s)
Observable caliente, efecto secundario se ejecuta una sola vez,
Observador 1: 0,
(1s)
Observable caliente, efecto secundario se ejecuta una sola vez,
Observador 1: 1,
Observador tardío: 1,
*/
```

**Compartir el Observable fuente utilizando un ReplaySubject**

Al utilizar un ReplaySubject en lugar de un Sujeto normal, los observadores que se suscriban más tarde sí que recibirán los valores que se hayan emitido anteriormente.

[StackBlitz](https://stackblitz.com/edit/docu-rxjs-multicast-3?file=index.ts)

```javascript
import { ConnectableObservable, interval, ReplaySubject, timer } from "rxjs";
import { take, tap, multicast } from "rxjs/operators";

const number$ = interval(1000).pipe(take(2));

const multicasted$ = number$.pipe(
  tap(() =>
    console.log(
      "Observable caliente, efecto secundario se ejecuta una sola vez"
    )
  ),
  // Se utiliza un ReplaySubject en lugar de un Subject
  multicast(() => new ReplaySubject())
) as ConnectableObservable<number>;

timer(3000)
  .pipe(tap(() => console.log("Conectado")))
  .subscribe(() => multicasted$.connect());

multicasted$.subscribe(val => console.log(`Observador 1: ${val}`));

// Aunque el observador se suscriba más tarde, recibirá los valores que ya se hayan emitido, gracias al ReplaySubject
timer(5000)
  .pipe(
    tap(() =>
      multicasted$.subscribe(val => console.log(`Observador tardío: ${val}`))
    )
  )
  .subscribe();

/* Salida:
(3s)
Conectado
(1s)
Observable caliente, efecto secundario se ejecuta una sola vez,
Observador 1: 0,
Observador tardío: 0
(1s)
Observable caliente, efecto secundario se ejecuta una sola vez,
Observador 1: 1,
Observador tardío: 1
*/
```

<details>

<summary>Sobrecargas</summary>

#### Firma

`multicast(subject: Subject<T>): UnaryFunction<Observable<T>, ConnectableObservable<T>>`

#### Parámetros

#### Retorna

`UnaryFunction<Observable<T>, ConnectableObservable<T>>`

#### Firma

`multicast(subject: Subject<T>, selector: (shared: Observable<T>) => O): UnaryFunction<Observable<T>, ConnectableObservable<ObservedValueOf<O>>>`

#### Parámetros

#### Retorna

`UnaryFunction<Observable<T>, ConnectableObservable<ObservedValueOf<O>>>`

#### Firma

`multicast(subjectFactory: (this: Observable<T>) => Subject<T>): UnaryFunction<Observable<T>, ConnectableObservable<T>>`

#### Parámetros

#### Retorna

`UnaryFunction<Observable<T>, ConnectableObservable<T>>`

#### Firma

`multicast(SubjectFactory: (this: Observable<T>) => Subject<T>, selector: (shared: Observable<T>) => O): OperatorFunction<T, ObservedValueOf<O>>`

#### Parámetros

#### Retorna

`OperatorFunction<T, ObservedValueOf<O>>`

</details>

### Recursos adicionales

[![Source code](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/multicasting/assets/icons/source-code.png)](https://github.com/ReactiveX/rxjs/blob/master/src/internal/operators/multicast.ts)

[Documentación oficial en inglés](https://rxjs.dev/api/operators/multicast)


# publish

Retorna un ConnectableObservable, que es un Observable que espera a que se haga una llamada a su método \`connect\` antes de empezar a emitir valores a sus Observadores

💡 publish es equivalente a `multicast(() => new Subject())`

<details>

<summary>Signatura</summary>

#### Firma

`publish<T, R>(selector?: OperatorFunction<T, R>): MonoTypeOperatorFunction<T> | OperatorFunction<T, R>`

#### Parámetros

#### Retorna

`MonoTypeOperatorFunction<T> | OperatorFunction<T, R>`: Un `ConnectableObservable` que, cuando se hace una llamada a su método `connect`, hace que el Observable fuente emita valores a sus Observadores.

</details>

## Descripción

Convierte un Observable frío en un Observable caliente, utilizando el operador [multicast](https://github.com/puntotech/rxjs-docu/blob/master/operators/multicasting/multicast/README.md) junto a un Sujeto internamente.

![Diagrama de canicas del operador publish](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/multicasting/assets/images/marble-diagrams/multicasting/publish.png)

Retorna un ConnectableObservable, que es un Observable que espera a que se haga una llamada a su método `connect` antes de empezar a emitir valores a sus Observadores. En el caso de que no se llame a `connect`, el Observable fuente no emitirá ningún valor.

💡 Para evitar tener que llamar a connect manualmente, se puede utilizar el [operador refCount](https://github.com/puntotech/rxjs-docu/blob/master/operators/multicasting/refCount/README.md).

## Ejemplos

**Compartir el Observable fuente con publish**

[StackBlitz](https://stackblitz.com/edit/docu-rxjs-publish?file=index.ts)

```typescript
import { ConnectableObservable, interval, timer } from "rxjs";
import { publish, tap, take } from "rxjs/operators";

// number$ no empezará a emitir valores hasta que se haga una llamada a connect
const number$ = interval(1000).pipe(take(4));

const multicasted$ = number$.pipe(
  tap(() =>
    console.log("Fuente compartida, efecto secundario se ejecuta una sola vez")
  ),
  publish()
) as ConnectableObservable<number>;

// Llamando a connect tras 3 seconds
timer(3000)
  .pipe(tap(() => multicasted$.connect()))
  .subscribe();

multicasted$.subscribe((val) => console.log(`Observador 1: ${val}`));
multicasted$.subscribe((val) => console.log(`Observador 2: ${val}`));

/* Salida:
Fuente compartida, efecto secundario se ejecuta una sola vez,
Observador 1: 0,
Observador 2: 0,
(1s)
Fuente compartida, efecto secundario se ejecuta una sola vez,
Observador 1: 1,
Observador 2: 1,
...
*/
```

### Ejemplos de la documentación oficial

Convertir al Observable fuente en caliente, unir cada Observable interno en uno solo y suscribirse al Observable resultante

```javascript
import { of, zip, interval, merge } from "rxjs";
import { map, publish, tap } from "rxjs/operators";

const source$ = zip(interval(2000), of(1, 2, 3, 4, 5, 6, 7, 8, 9)).pipe(
  map((values) => values[1])
);

source$
  .pipe(
    publish((multicasted$) =>
      merge(
        multicasted$.pipe(tap((x) => console.log("Flujo 1:", x))),
        multicasted$.pipe(tap((x) => console.log("Flujo 2:", x))),
        multicasted$.pipe(tap((x) => console.log("Flujo 3:", x)))
      )
    )
  )
  .subscribe();

// Cada 2 segundos:
// 'Flujo 1: 1'
// 'Flujo 2: 1'
// 'Flujo 3: 1'
// ...
// 'Flujo 1: 9'
// 'Flujo 2: 9'
// 'Flujo 3: 9'
```

<details>

<summary>Sobrecargas</summary>

#### Firma

`publish(): UnaryFunction<Observable<T>, ConnectableObservable<T>>`

#### Parámetros

No recibe ningún parámetro.

#### Retorna

`UnaryFunction<Observable<T>, ConnectableObservable<T>>`

#### Firma

`publish(selector: (shared: Observable<T>) => O): OperatorFunction<T, ObservedValueOf<O>>`

#### Parámetros

#### Retorna

`OperatorFunction<T, ObservedValueOf<O>>`

#### Firma

`publish(selector: MonoTypeOperatorFunction<T>): MonoTypeOperatorFunction<T>`

#### Parámetros

#### Retorna

`MonoTypeOperatorFunction<T>`

</details>

### Recursos adicionales

[![Source code](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/multicasting/assets/icons/source-code.png)](https://github.com/ReactiveX/rxjs/blob/master/src/internal/operators/publish.ts)

[Documentación oficial en inglés](https://rxjs.dev/api/operators/publish)


# publishBehavior

Comparte el Observable fuente, permitiendo proporcionar un valor por defecto

💡 publishBehavior es equivalente a `multicast(() => new BehaviorSubject())`

<details>

<summary>Signatura</summary>

#### Firma

`publishBehavior<T>(value: T): UnaryFunction<Observable<T>, ConnectableObservable<T>>`

#### Parámetros

#### Retorna

`UnaryFunction<Observable<T>, ConnectableObservable<T>>`

</details>

## Descripción

Comparte el Observable fuente, permitiendo proporcionar un valor por defecto, ya que utiliza un BehaviorSubject internamente.

Retorna un ConnectableObservable, que es un Observable que espera a que se haga una llamada a su método `connect` antes de empezar a emitir valores a sus Observadores. En el caso de que no se llame a `connect`, el Observable fuente no emitirá ningún valor.

💡 Para evitar tener que llamar a connect manualmente, se puede utilizar el [operador refCount](https://github.com/puntotech/rxjs-docu/blob/master/operators/multicasting/refCount/README.md).

## Ejemplos

**Compartir el Observable fuente, proporcionando un valor inicial de -1**

[StackBlitz](https://stackblitz.com/edit/docu-rxjs-publish?file=index.ts)

```typescript
import { ConnectableObservable, interval, timer } from "rxjs";
import { publishBehavior, tap, take } from "rxjs/operators";

// number$ no empezará a emitir valores hasta que se haga una llamada a connect
const number$ = interval(1000).pipe(take(4));

const multicasted$ = number$.pipe(
  tap(() =>
    console.log("Fuente compartida, efecto secundario se ejecuta una sola vez")
  ),
  publishBehavior(-1)
) as ConnectableObservable<number>;

// Llamando a connect tras 3 segundos
timer(3000)
  .pipe(tap(() => multicasted$.connect()))
  .subscribe();

multicasted$.subscribe((val) => console.log(`Observador 1: ${val}`));
multicasted$.subscribe((val) => console.log(`Observador 2: ${val}`));

/* Salida:
Observador 1: -1, 
Observador 2: -1,
(3s)
Fuente compartida, efecto secundario se ejecuta una sola vez,
Observador 1: 0, 
Observador 2: 0,
(1s)
Fuente compartida, efecto secundario se ejecuta una sola vez,
Observador 1: 1,
Observador 2: 1,
...
*/
```

### Recursos adicionales

[![Source code](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/multicasting/assets/icons/source-code.png)](https://github.com/ReactiveX/rxjs/blob/master/src/internal/operators/publishBehavior.ts)

[Documentación oficial en inglés](https://rxjs.dev/api/operators/publishBehavior)


# publishLast

Comparte el Observable fuente, emitiendo únicamente el último valor emitido a los observadores

💡 publishLast es equivalente a `multicast(() => new AsyncSubject())`

<details>

<summary>Signatura</summary>

#### Firma

`publishLast<T>(): UnaryFunction<Observable<T>, ConnectableObservable<T>>`

#### Parámetros

No recibe ningún parámetro.

### Retorna

`UnaryFunction<Observable<T>, ConnectableObservable<T>>`: Una secuencia observable que contiene los elementos de una secuencia producida al multidifundir la secuencia fuente.

</details>

## Descripción

Retorna una secuencia Observable conectable que comparte una sola suscripción a la secuencia subyacente, que contiene solo la última notificación. Para ello utiliza el operador [multicast](https://github.com/puntotech/rxjs-docu/blob/master/operators/multicasting/multicast/README.md) junto a un AsyncSubject internamente.

![Diagrama de canicas del operador publishLast](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/multicasting/assets/images/marble-diagrams/multicasting/publishLast.png)

Es similar a [publish](https://github.com/puntotech/rxjs-docu/blob/master/operators/multicasting/publish/README.md), pero espera a que el Observable fuente se complete, para almacenar su último valor emitido. Al igual que [publishReplay](https://github.com/puntotech/rxjs-docu/blob/master/operators/multicasting/publishReplay/README.md) y [publishBehavior](https://github.com/puntotech/rxjs-docu/blob/master/operators/multicasting/publishBehavior/README.md), almacena este último valor emitido aunque no tenga ningún suscriptor. Si llega un suscriptor nuevo, este recibirá el valor almacenado y se completará.

## Ejemplos

**Compartir el Observable fuente, emitiendo únicamente su último valor**

[StackBlitz](https://stackblitz.com/edit/docu-rxjs-publishlast?file=index.html)

```typescript
import { ConnectableObservable, interval, timer } from "rxjs";
import { publishLast, tap, take } from "rxjs/operators";

// number$ no empezará a emitir valores hasta que se haga una llamada a connect
const number$ = interval(1000).pipe(take(4));

const multicasted$ = number$.pipe(publishLast()) as ConnectableObservable<
  number
>;

// Llamando a connect
multicasted$.connect();

multicasted$.subscribe((val) => console.log(`Observador 1: ${val}`));
multicasted$.subscribe((val) => console.log(`Observador 2: ${val}`));

/* Salida:
(4s)
Observador 1: 3,
Observador 2: 3
*/
```

**Si el Observable fuente no llega a completarse, nunca se emitirá ningún valor**

[StackBlitz](https://stackblitz.com/edit/docu-rxjs-publishlast-2?file=index.ts)

```javascript
import { ConnectableObservable, interval } from "rxjs";
import { publishLast } from "rxjs/operators";

// El Observable fuente nunca se completa
const number$ = interval(1000);

const multicasted$ = number$.pipe(publishLast()) as ConnectableObservable<
  number
>;

// Llamando a connect
multicasted$.connect();

multicasted$.subscribe(val => console.log(`Observador 1: ${val}`));
multicasted$.subscribe(val => console.log(`Observador 2: ${val}`));
// Salida:
```

### Ejemplo de la documentación oficial

```javascript
import { interval } from "rxjs";
import { publishLast, tap, take } from "rxjs/operators";

const connectable = interval(1000).pipe(
  tap((x) => console.log("side effect", x)),
  take(3),
  publishLast()
);

connectable.subscribe(
  (x) => console.log("Sub. A", x),
  (err) => console.log("Sub. A Error", err),
  () => console.log("Sub. A Complete")
);

connectable.subscribe(
  (x) => console.log("Sub. B", x),
  (err) => console.log("Sub. B Error", err),
  () => console.log("Sub. B Complete")
);

connectable.connect();

// Salida:
//    "side effect 0"
//    "side effect 1"
//    "side effect 2"
//    "Sub. A 2"
//    "Sub. B 2"
//    "Sub. A Complete"
//    "Sub. B Complete"
```

### Recursos adicionales

[![Source code](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/multicasting/assets/icons/source-code.png)](https://github.com/ReactiveX/rxjs/blob/master/src/internal/operators/publishLast.ts)

[Documentación oficial en inglés](https://rxjs.dev/api/operators/publishLast)


# publishReplay

Comparte el Observable fuente, permitiendo que los observadores que se suscriban tarde puedan recibir los valores que se hayan emitido anteriormente

💡 publishReplay es equivalente a `multicast(() => new ReplaySubject())`

<details>

<summary>Signatura</summary>

#### Firma

`publishReplay<T, R>(bufferSize?: number, windowTime?: number, selectorOrScheduler?: SchedulerLike | OperatorFunction<T, R>, scheduler?: SchedulerLike): UnaryFunction<Observable<T>, ConnectableObservable<R>>`

#### Parámetros

#### Retorna

`UnaryFunction<Observable<T>, ConnectableObservable<R>>`

</details>

## Descripción

Comparte el Observable fuente, permitiendo que los observadores que se suscriban tarde puedan recibir los valores que se hayan emitido anteriormente.

Retorna un ConnectableObservable, que es un Observable que espera a que se haga una llamada a su método `connect` antes de empezar a emitir valores a sus Observadores. En el caso de que no se llame a `connect`, el Observable fuente no emitirá ningún valor.

💡 Para evitar tener que llamar a connect manualmente, se puede utilizar el [operador refCount](https://github.com/puntotech/rxjs-docu/blob/master/operators/multicasting/refCount/README.md).

## Ejemplos

**Compartir el Observable fuente**

Los observadores que se suscriban más tarde recibirán los valores emitidos anteriormente en el momento en el que se suscriban.

[StackBlitz](https://stackblitz.com/edit/docu-rxjs-publishreplay?file=index.ts)

```javascript
import { ConnectableObservable, interval, Subject, timer } from "rxjs";
import { publishReplay, take, tap } from "rxjs/operators";

const number$ = interval(1000).pipe(take(4));

const multicasted$ = number$.pipe(
  tap(() =>
    console.log("Fuente compartida, efecto secundario se ejecuta una sola vez")
  ),
  publishReplay()
) as ConnectableObservable<number>;

multicasted$.connect();

multicasted$.subscribe(val => console.log(`Observador 1: ${val}`));

timer(3000)
  .pipe(
    tap(() =>
      multicasted$.subscribe(val => console.log(`Observador tardío: ${val}`))
    )
  )
  .subscribe();

/* Salida:
  Fuente compartida, efecto secundario se ejecuta una sola vez,
  Observador 1: 0,
  (1s)
  Fuente compartida, efecto secundario se ejecuta una sola vez,
  Observador 1: 1,
  (1s)
  Fuente compartida, efecto secundario se ejecuta una sola vez,
  Observador 1: 2,
  Observador tardío: 0,
  Observador tardío: 1,
  Observador tardío: 2,
  (1s)
  Fuente compartida, efecto secundario se ejecuta una sola vez,
  Observador 1: 3,
  Observador tardío: 3
*/
```

### Recursos adicionales

[![Source code](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/multicasting/assets/icons/source-code.png)](https://github.com/ReactiveX/rxjs/blob/master/src/internal/operators/publishReplay.ts)

[Documentación oficial en inglés](https://rxjs.dev/api/operators/publishReplay)


# refCount

Hace que un ConnectableObservable se comporte como un Obesrvable normal, y automatiza la forma de conectarse a él

💡 Utilizar el operador [share](https://github.com/puntotech/rxjs-docu/blob/master/operators/multicasting/share/README.md) es equivalente a utilizar el operador [publish](https://github.com/puntotech/rxjs-docu/blob/master/operators/multicasting/publish/README.md) (convirtiendo el Observable en uno caliente) junto al operador refCount.

<details>

<summary>Signatura</summary>

#### Firma

`refCount<T>(): MonoTypeOperatorFunction<T>`

#### Parámetros

No recibe ningún parámetro.

### Retorna

`MonoTypeOperatorFunction<T>`

</details>

## Descripción

Al utilizar alguna de las variantes del operador [publish](https://github.com/puntotech/rxjs-docu/blob/master/operators/multicasting/publish/README.md), o el operador [multicast](https://github.com/puntotech/rxjs-docu/blob/master/operators/multicasting/multicast/README.md), era necesario llamar manualmente al método connect() para suscribirse a la fuente y, posteriormente, gestionar la cancelación de la suscripción para evitar posibles pérdidas de memoria.

Para que automatizar el proceso y evitar errores, se creó el operador refCount, que hace ambas cosas automáticamente.

![Diagrama de canicas del operador refCount](https://github.com/puntotech/rxjs-docu/blob/master/assets/images/marble-diagrams/multicasting/refCount.png)

Internamente, cuenta las suscripciones al Observable y se suscribe (una sola vez) a la fuente si el número de suscripciones es mayor que 0. Si el número de suscripciones es menor que 1, se cancela la suscripción a la fuente. De esta manera se puede garantizar que cualquier operador anterior a `refCount` se ejecuta una única vez por cada evento, independientemente del número de suscripciones al Observable objetivo.

## Ejemplos

**Compartir el Observable fuente de forma automática con multicast + refCount**

[StackBlitz](https://stackblitz.com/edit/docu-rxjs-refcount-multicast?file=index.ts)

```javascript
import { interval, Subject, timer } from "rxjs";
import { take, takeUntil, tap, multicast, refCount } from "rxjs/operators";

const number$ = interval(1000).pipe(take(10));

// En lugar de cancelar la suscripción manualmente, se va a utilizar la técnica takeUntil + Subject
const stop$ = new Subject();

const multicasted$ = number$.pipe(
  tap(() =>
    console.log("Fuente compartida, efecto secundario se ejecuta una sola vez")
  ),
  multicast(() => new Subject()),
  // Al usar refCount, ya no es necesario llamar a connect() manualmente
  refCount(),
  takeUntil(stop$)
);

// refCount === 1, se hace la suscripción a number$
multicasted$.subscribe((val) => console.log(`Observador 1: ${val}`));
// refCount === 2
multicasted$.subscribe((val) => console.log(`Observador 2: ${val}`));

// refCount === 0, se cancela la suscripción a number$
timer(2000)
  .pipe(
    tap(() => stop$.next()),
    tap(() => console.log("Fin"))
  )
  .subscribe();

/* Salida:
  Fuente compartida, efecto secundario se ejecuta una sola vez,
  Observador 1: 0,
  Observador 2: 0,
  (1s)
  Fuente compartida, efecto secundario se ejecuta una sola vez,
  Observador 1: 1,
  Observador 2: 1,
  (1s) 
  Fin
 */
```

**Compartir el Observable fuente de forma automática con publish + refCount**

💡 El operador publish es equivalente a `multicast(() => new Subject())`

[StackBlitz](/operadores/multicasting/refcount)

```javascript
import { interval, Subject, timer } from "rxjs";
import { take, takeUntil, tap, multicast, refCount } from "rxjs/operators";

const number$ = interval(1000).pipe(take(10));

// En lugar de cancelar la suscripción manualmente, se va a utilizar la técnica takeUntil + Subject
const stop$ = new Subject();

const multicasted$ = number$.pipe(
  tap(() =>
    console.log("Fuente compartida, efecto secundario se ejecuta una sola vez")
  ),
  multicast(() => new Subject()),
  // Al usar refCount, ya no es necesario llamar a connect() manualmente
  refCount(),
  takeUntil(stop$)
);

// refCount === 1, se hace la suscripción a number$
multicasted$.subscribe((val) => console.log(`Observador 1: ${val}`));
// refCount === 2
multicasted$.subscribe((val) => console.log(`Observador 2: ${val}`));

// refCount === 0, se cancela la suscripción a number$
timer(2000)
  .pipe(
    tap(() => stop$.next()),
    tap(() => console.log("Fin"))
  )
  .subscribe();

/* Salida:
  Fuente compartida, efecto secundario se ejecuta una sola vez,
  Observador 1: 0,
  Observador 2: 0,
  (1s)
  Fuente compartida, efecto secundario se ejecuta una sola vez,
  Observador 1: 1,
  Observador 2: 1,
  (1s) 
  Fin
 */
```

**Compartir el Observable fuente de forma automática con publishReplay + refCount**

💡 El operador publish es equivalente a `multicast(() => new ReplaySubject())`.

Para que los observadores que se suscriban tarde puedan recibir los valores que se hayan emitido anterioremente, se puede utilizar publishReplay:

[StackBlitz](https://stackblitz.com/edit/docu-rxjs-refcount-publishreplay?file=index.ts)

```javascript
import { interval, Subject, timer } from "rxjs";
import { publishReplay, take, takeUntil, tap, refCount } from "rxjs/operators";

const number$ = interval(1000).pipe(take(10));

const stop$ = new Subject();

const multicasted$ = number$.pipe(
  tap(() =>
    console.log("Fuente compartida, efecto secundario se ejecuta una sola vez")
  ),
  publishReplay(),
  refCount(),
  takeUntil(stop$)
);

// refCount === 1, se hace la suscripción a number$
multicasted$.subscribe((val) => console.log(`Observador 1: ${val}`));

// refCount === 2
timer(3000)
  .pipe(
    tap(() =>
      multicasted$.subscribe((val) => console.log(`Observador tardío: ${val}`))
    )
  )
  .subscribe();

// refCount === 0, se cancela la suscripción a number$
timer(4000)
  .pipe(
    tap(() => stop$.next()),
    tap(() => console.log("Fin"))
  )
  .subscribe();

/* Salida:
  Fuente compartida, efecto secundario se ejecuta una sola vez,
  Observador 1: 0,
  (1s)
  Fuente compartida, efecto secundario se ejecuta una sola vez,
  Observador 1: 1,
  (1s) 
  Fuente compartida, efecto secundario se ejecuta una sola vez,
  Observador 1: 2,
  Observador tardío: 0,
  Observador tardío: 1,
  Observador tardío: 2,
  (1s)
  Fuente compartida, efecto secundario se ejecuta una sola vez,
  Observador 1: 3,
  Observador tardío: 3,
  Fin
*/
```

### Ejemplo de la documentación oficial

En el siguiente ejemplo hay dos Observables intervalo transformados en Observables conectables mediante el operador `publish`. El primero utiliza el operador `refCount`, mientras que el segundo no. Se debe tener en cuenta que un Observable conectable no hace nada hasta que no se haga una llamada a su función `connect`.

```javascript
import { interval } from "rxjs";
import { tap, publish, refCount } from "rxjs/operators";

// Transformar el Observable interval en un ConnectableObservable (caliente)
const refCountInterval = interval(400).pipe(
  tap((num) => console.log(`refCount ${num}`)),
  publish(),
  refCount()
);

const publishedInterval = interval(400).pipe(
  tap((num) => console.log(`publish ${num}`)),
  publish()
);

refCountInterval.subscribe();
refCountInterval.subscribe();
/* 'refCount 0' -----> 'refCount 1' -----> etc.
 Todas las subscripciones recibirán el mismo valor y tanto tap como cualquier otro operador
 que esté antes del operador publish se ejecutará una vez por cada evento, independientemente del número de suscripciones
*/

publishedInterval.subscribe();
// No ocurre nada hasta que no se llame a la función connect() del Observable
```

### Recursos adicionales

[![Source code](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/multicasting/assets/icons/source-code.png)](https://github.com/ReactiveX/rxjs/blob/master/src/internal/operators/refCount.ts)

[Documentación oficial en inglés](https://rxjs.dev/api/operators/refCount)


# share

Comparte el Observable fuente entre varios suscriptores

💡 Se puede utilizar share para convertir un Observable frío en uno caliente

💡 share es como utilizar [multicast](https://github.com/puntotech/rxjs-docu/blob/master/operators/multicasting/multicast/README.md) con un Sujeto y [refCount](https://github.com/puntotech/rxjs-docu/blob/master/operators/multicasting/refCount/README.md)

<details>

<summary>Signatura</summary>

### Firma

`share<T>(): MonoTypeOperatorFunction<T>`

### Parámetros

No recibe ningún parámetro.

### Retorna

`MonoTypeOperatorFunction<T>`: Un Observable que, al ser conectado, hace que el Observable fuente emita valores a sus Observadores.

</details>

## Descripción

Comparte las emisiones del Observable fuente entre todos sus suscriptores.

![Diagrama de canicas del operador share](https://github.com/puntotech/rxjs-docu/blob/master/assets/images/marble-diagrams/multicasting/share.png)

Retorna un Observable nuevo que multidifunde (comparte) el Observable original. Mientras haya al menos un suscriptor, el Observable emitirá valores. Cuando todos los Suscriptores hayan cancelado la suscripción al Observable compartido, `share` cancelará la suscripción al Observable fuente. Dado que el Observable está multidifundido, el flujo es caliente.

`share` es un alias de `multicast(() => new Subject()), refCount()`.

## Ejemplos

Por defecto, los Observables son fríos. Esto quiere decir que con cada suscripción, se vuelve a crear el productor subyacente. Por tanto, si un Observable realiza una petición AJAX, cada vez que reciba una suscripción nueva, **volverá a hacer la petición**. Este comportamiento se puede observar en el siguiente ejemplo:

[StackBlitz](https://stackblitz.com/edit/docu-rxjs-share?file=index.ts)

```javascript
import { map, mergeAll, take, tap } from "rxjs/operators";
import { ajax } from "rxjs/ajax";

const ghibliFilm$ = ajax.getJSON("https://ghibliapi.herokuapp.com/films").pipe(
  tap((_) => console.log("Nueva petición")),
  mergeAll(),
  take(1)
);

const ghibliFilmTitle$ = ghibliFilm$.pipe(map(({ title }) => title));

const ghibliFilmDescription$ = ghibliFilm$.pipe(
  map(({ description }) => description)
);

ghibliFilmTitle$.subscribe(console.log);
ghibliFilmDescription$.subscribe(console.log);

/* Salida: 
'Nueva petición'
'Castle in the Sky',
'Nueva petición',
'The orphan Sheeta inherited a mysterious crystal that links her to the mythical...'
*/
```

Sin embargo, si se utiliza el operador `share` para multidifundir (compartir) los valores del Observable entre todos sus suscriptores. De esta manera, el Observable frío se convierte en uno caliente, y, en el caso del ejemplo anterior, la petición AJAX **no se repite** con cada nueva suscripción.

[StackBlitz](https://stackblitz.com/edit/docu-rxjs-share-2?file=index.ts)

```javascript
import { map, mergeAll, share, take, tap } from "rxjs/operators";
import { ajax } from "rxjs/ajax";

const ghibliFilm$ = ajax.getJSON("https://ghibliapi.herokuapp.com/films").pipe(
  tap((_) => console.log("Nueva petición")),
  mergeAll(),
  take(1),
  share()
);

const ghibliFilmTitle$ = ghibliFilm$.pipe(map(({ title }) => title));

const ghibliFilmDescription$ = ghibliFilm$.pipe(
  map(({ description }) => description)
);

ghibliFilmTitle$.subscribe(console.log);

ghibliFilmDescription$.subscribe(console.log);
/* Salida:
'Nueva petición'
'Castle in the Sky',
'The orphan Sheeta inherited a mysterious crystal that links her to the mythical...'
*/
```

### Recursos adicionales

[![Source code](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/multicasting/assets/icons/source-code.png)](https://github.com/ReactiveX/rxjs/blob/master/src/internal/operators/share.ts)

[Documentación oficial en inglés](https://rxjs.dev/api/operators/share)


# shareReplay

Comparte el Observable fuente entre varios suscriptores, repitiendo las últimas n emisiones con cada suscripción

💡 La capacidad de repetir emisiones es lo que diferencia a shareReplay de [share](https://github.com/puntotech/rxjs-docu/blob/master/operators/multicasting/share/README.md)

<details>

<summary>Signatura</summary>

#### Firma

`shareReplay<T>(configOrBufferSize?: number | ShareReplayConfig, windowTime?: number, scheduler?: SchedulerLike): MonoTypeOperatorFunction<T>`

#### Parámetros

#### Retorna

`MonoTypeOperatorFunction<T>`

</details>

## Descripción

### Recursos adicionales

[![Source code](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/multicasting/assets/icons/source-code.png)](https://github.com/ReactiveX/rxjs/blob/master/src/internal/operators/shareReplay.ts)

[Documentación oficial en inglés](https://rxjs.dev/api/operators/shareReplay)


# Transformación

* [buffer](/operadores/transformation/buffer)
* [bufferCount](/operadores/transformation/buffercount)
* [bufferTime](/operadores/transformation/buffertime)
* [bufferToggle](/operadores/transformation/buffertoggle)
* [bufferWhen](/operadores/transformation/bufferwhen)
* [concatMap](/operadores/transformation/concatmap)
* [exhaustMap](/operadores/transformation/exhaustmap)
* [expand](/operadores/transformation/expand)
* [groupBy](/operadores/transformation/groupby)
* [map](/operadores/transformation/map)
* [mergeMap](/operadores/transformation/mergemap)
* [mergeScan](/operadores/transformation/mergescan)
* [pairwise](/operadores/transformation/pairwise)
* [scan](/operadores/transformation/scan)
* [switchMap](/operadores/transformation/switchmap)
* [window](/operadores/transformation/window)
* [windowCount](/operadores/transformation/windowcount)
* [windowTime](/operadores/transformation/windowtime)
* [windowToggle](/operadores/transformation/windowtoggle)
* [windowWhen](/operadores/transformation/windowwhen)

## Operadores obsoletos

* [concatMapTo](/operadores/transformation/concatmapto) (obsoleto)
* [exhaust](/operadores/transformation/exhaust) (obsoleto)
* [mapTo](/operadores/transformation/mapto)
* [mergeMapTo](/operadores/transformation/mergemapto) (obsoleto)
* [partition](/operadores/transformation/partition)
* [pluck](/operadores/transformation/pluck) (obsoleto)
* [switchMapTo](/operadores/transformation/switchmapto) (obsoleto)


# buffer

Almacena los valores del Observable en un búfer hasta que otro Observable emita

<details>

<summary>Signatura</summary>

#### Firma

`buffer<T>(closingNotifier: Observable<any>): OperatorFunction<T, T[]>`

#### Parámetros

#### Retorna

`OperatorFunction<T, T[]>`: Un Observable de búferes, que son arrays de valores.

</details>

## Descripción

Acumula valores en un array, y emite dicho array cuando un segundo Observable emita.

![Diagrama de canicas del operador buffer](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/transformation/assets/images/marble-diagrams/transformation/buffer.png)

Almacena los valores del Observable fuente en un búfer hasta que el Observable `closingNotifier` emita un valor, en cuyo momento se emite el búfer en el Observable resultante, y se abre un búfer nuevo internamente, esperando a la próxima emisión de `closingNotifier`.

## Ejemplos

**Con cada tecla pulsada, emitir el array de los números emitidos desde la última tecla pulsada**

[StackBlitz](https://stackblitz.com/edit/rxjs-buffer-1?file=index.ts)

```typescript
import { buffer } from "rxjs/operators";
import { interval, fromEvent } from "rxjs";

const number$ = interval(1000);
const key$ = fromEvent(document, "keydown");

number$.pipe(buffer(key$)).subscribe(console.log);
// Salida: (tecla pulsada) [0, 1, 2, 3] (tecla pulsada) [4, 5]
```

**Emitir los clicks hechos en un intervalo de 5 segundos**

Si no se hace ningún click en el intervalo, no se emitirá nada.

[StackBlitz](https://stackblitz.com/edit/rxjs-buffer-2?file=index.ts)

```javascript
import { buffer, filter } from "rxjs/operators";
import { interval, fromEvent } from "rxjs";

const click$ = fromEvent(document, "click");
const clickInterval$ = interval(5000);

click$
  .pipe(
    buffer(clickInterval$),
    filter(({ length }) => length > 0)
  )
  .subscribe(console.log);
// Output: (5s) [MouseEvent, MouseEvent] (5s) [MouseEvent]
```

### Ejemplos de la documentación oficial

**Emite el array de eventos almacenados en cada click**

```javascript
import { fromEvent, interval } from "rxjs";
import { buffer } from "rxjs/operators";

const clicks = fromEvent(document, "click");
const intervalEvents = interval(1000);
const buffered = intervalEvents.pipe(buffer(clicks));
buffered.subscribe((x) => console.log(x));
```

### Recursos adicionales

[![Source code](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/transformation/assets/icons/source-code.png)](https://github.com/ReactiveX/rxjs/blob/master/src/internal/operators/buffer.ts)

[Documentación oficial en inglés](https://rxjs.dev/api/operators/buffer)


# bufferCount

Almacena los valores del Observable en un búfer hasta que este alcanza el tamaño máximo indicado

<details>

<summary>Signatura</summary>

#### Firma

`bufferCount<T>(bufferSize: number, startBufferEvery: number = null): OperatorFunction<T, T[]>`

#### Parámetros

#### Retorna

`OperatorFunction<T, T[]>`: Un Observable de arrays de valores almacenados.

</details>

## Descripción

Almacena valores en un array, y emite dicho array cuando su tamaño sea el especificado por `bufferSize`.

![Diagrama de canicas del operador bufferCount](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/transformation/assets/images/marble-diagrams/transformation/bufferCount.png)

Almacena valores del Observable fuente y emite el búfer cuando este llega al tamaño de `bufferSize`, y abre un nuevo búfer cada `startBufferEvery` emisiones. Si no se proporciona `startBufferEvery` o su valor es `null`, entonces se abre un nuevo búfer inmediatamente después de que se cierre y se emita el búfer anterior.

## Ejemplos

**Almacenar cada 5 valores en un array y emitirlo**

[StackBlitz](https://stackblitz.com/edit/rxjs-buffercount-1?file=index.ts)

```javascript
import { bufferCount } from "rxjs/operators";
import { interval } from "rxjs";

const number$ = interval(1000);

number$.pipe(bufferCount(5)).subscribe(console.log);
// Output: [0, 1, 2, 3, 4], [5, 6, 7, 8, 9]...
```

### Ejemplos de la documentación oficial

**Emitir los últimos dos eventos click en un array**

```javascript
import { fromEvent } from "rxjs";
import { bufferCount } from "rxjs/operators";

const clicks = fromEvent(document, "click");
const buffered = clicks.pipe(bufferCount(2));
buffered.subscribe((x) => console.log(x));
```

**En cada click, emitir los dos últimos eventos click en un array**

```javascript
import { fromEvent } from "rxjs";
import { bufferCount } from "rxjs/operators";

const clicks = fromEvent(document, "click");
const buffered = clicks.pipe(bufferCount(2, 1));
buffered.subscribe((x) => console.log(x));
```

### Recursos adicionales

[![Source code](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/transformation/assets/icons/source-code.png)](https://github.com/ReactiveX/rxjs/blob/master/src/internal/operators/bufferCount.ts)

[Documentación oficial en inglés](https://rxjs.dev/api/operators/bufferCount)


# bufferTime

Acumula valores del Observable fuente durante un periodo de tiempo

<details>

<summary>Signatura</summary>

#### Firma

`bufferTime<T>(bufferTimeSpan: number): OperatorFunction<T, T[]>`

#### Parámetros

#### Retorna

`OperatorFunction<T, T[]>`: Un Observable de arrays de valores almacenados.

</details>

## Descripción

Almacena valores en un array, y emite esos arrays periódicamente en el tiempo.

![Diagrama de canicas del operador bufferTime](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/transformation/assets/images/marble-diagrams/transformation/bufferTime.png)

Acumula valores de la fuente durante un periodo de tiempo determinado por `bufferTimeSpan`. Si no se proporciona el argumento opcional `bufferCreationInterval`, se emitirá y reseteará el búfer cada `bufferTimeSpan` milisegundos. En el caso de que sí se proporcione, `bufferTime` abrirá y el búfer cada `bufferCreationInterval` milisegundos y lo cerrará (emitiendo y reseteándolo) cada `bufferTimeSpan` milisegundos. Cuando se proporcione el argumento opcional `maxBufferSize`, el búfer se cerrará o cada `buffertimeSpan` milisegundos o cuando alcance el tamaño especificado por `maxBufferSize`.

## Ejemplos

**Almacenar valores en un array durante un periodo de 5 segundos y emitir el array**

[StackBlitz](https://stackblitz.com/edit/rxjs-buffertime-1?file=index.ts)

```javascript
import { bufferTime } from "rxjs/operators";
import { interval } from "rxjs";

const number$ = interval(1000);

number$.pipe(bufferTime(5000)).subscribe(console.log);
// Salida: [0, 1, 2, 3], [4, 5, 6, 7, 8]...
```

### Ejemplos de la documentación oficial

**Cada segundo, emitir un array de eventos click**

```javascript
import { fromEvent } from "rxjs";
import { bufferTime } from "rxjs/operators";

const clicks = fromEvent(document, "click");
const buffered = clicks.pipe(bufferTime(1000));
buffered.subscribe((x) => console.log(x));
```

**Cada 5 segundos, emitir los eventos click de los siguientes 2 segundos**

```javascript
import { fromEvent } from "rxjs";
import { bufferTime } from "rxjs/operators";

const clicks = fromEvent(document, "click");
const buffered = clicks.pipe(bufferTime(2000, 5000));
buffered.subscribe((x) => console.log(x));
```

<details>

<summary>Sobrecargas</summary>

#### Firma

`bufferTime(bufferTimeSpan: number, scheduler?: SchedulerLike): OperatorFunction<T, T[]>`

#### Parámetros

#### Retorna

`OperatorFunction<T, T[]>`

#### Firma

`bufferTime(bufferTimeSpan: number, bufferCreationInterval: number, scheduler?: SchedulerLike): OperatorFunction<T, T[]>`

#### Parámetros

#### Retorna

`OperatorFunction<T, T[]>`

#### Firma

`bufferTime(bufferTimeSpan: number, bufferCreationInterval: number, maxBufferSize: number, scheduler?: SchedulerLike): OperatorFunction<T, T[]>`

#### Parámetros

#### Retorna

`OperatorFunction<T, T[]>`

</details>

### Recursos adicionales

[![Source code](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/transformation/assets/icons/source-code.png)](https://github.com/ReactiveX/rxjs/blob/master/src/internal/operators/bufferTime.ts)

[Documentación oficial en inglés](https://rxjs.dev/api/operators/bufferTime)


# bufferToggle

Acumula valores del Observable fuente a partir de una emisión de openings en un búfer, que se cierra cuando el Observable retornado por la función closingSelector emite

<details>

<summary>Signatura</summary>

#### Firma

`bufferToggle<T, O>(openings: SubscribableOrPromise<O>, closingSelector: (value: O) => SubscribableOrPromise<any>): OperatorFunction<T, T[]>`

#### Parámetros

#### Retorna

`OperatorFunction<T, T[]>`: Un Observable de arrays de valores almacenados.

</details>

## Descripción

Almacena valores en un array. Abre el búfer cuando `openings` emite, y llama a la función `closingSelector` para obtener el Observable que indica cuándo cerrar el búfer.

![Diagrama de canicas del operador bufferToggle](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/transformation/assets/images/marble-diagrams/transformation/bufferToggle.png)

Almacena valores del Observable fuente abriendo el búfer cuando el Observable `openings` lo indica, cerrando dicho búfer y emitiéndolo cuando el `Subscribable` o la `Promise` retornados por la función `closingSelector` emiten.

## Ejemplos

**Abrir el búfer cada cuatro segundos, durante dos segundos**

[StackBlitz](https://stackblitz.com/edit/rxjs-buffertoggle-1?file=index.ts)

```javascript
import { fromEvent, interval } from "rxjs";
import { bufferToggle } from "rxjs/operators";

const number$ = interval(1000);

number$
  .pipe(bufferToggle(interval(4000), (_) => interval(2000)))
  .subscribe(console.log);
// Salida: [3, 4], [7, 8], [11, 12]...
```

**Emitir eventos MouseEvent mientras esté pulsado el botón del mouse, hasta que dejemos de pulsarlo**

[StackBlitz](https://stackblitz.com/edit/rxjs-buffertoggle-2?file=index.ts)

```typescript
import { fromEvent } from "rxjs";
import { bufferToggle } from "rxjs/operators";

const mouse$ = fromEvent<MouseEvent>(document, "mousemove");

mouse$
  .pipe(
    bufferToggle(fromEvent(document, "mousedown"), (_) =>
      fromEvent(document, "mouseup")
    )
  )
  .subscribe(console.log);
// Salida: [MouseEvent, MouseEvent, MouseEvent, MouseEvent]...
```

### Ejemplo de la documentación oficial

**Cada dos segundos, emite los eventos click de los siguientes 500 milisegundos**

```javascript
import { fromEvent, interval, EMPTY } from "rxjs";
import { bufferToggle } from "rxjs/operators";

const clicks = fromEvent(document, "click");
const openings = interval(1000);
const buffered = clicks.pipe(
  bufferToggle(openings, (i) => (i % 2 ? interval(500) : EMPTY))
);
buffered.subscribe((x) => console.log(x));
```

### Recursos adicionales

[![Source code](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/transformation/assets/icons/source-code.png)](https://github.com/ReactiveX/rxjs/blob/master/src/internal/operators/bufferToggle.ts)

[Documentación oficial en inglés](https://rxjs.dev/api/operators/bufferToggle)


# bufferWhen

Almacena valores y utiliza una función factoría de Observables para determinar cuándo cerrar, emitir y reiniciar el búfer

<details>

<summary>Signatura</summary>

#### Firma

`bufferWhen<T>(closingSelector: () => Observable<any>): OperatorFunction<T, T[]>`

#### Parámetros

#### Retorna

`OperatorFunction<T, T[]>`: Un Observable de arrays de valores almacenados.

</details>

## Descripción

Almacena valores en un array. Cuando comienza a almacenar valores, llama a una función que retorna un Observable que indica cuándo cerrar el búfer actual y abrir uno nuevo, para seguir almacenando valores.

![Diagrama de canicas del operador bufferWhen](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/transformation/assets/images/marble-diagrams/transformation/bufferWhen.png)

Abre un búfer de forma inmediata, que cierra cuando el Observable retornado por la función `closingSelector` emite un valor. En cuanto se cierra un búfer, se abre uno nuevo y se repite el proceso.

## Ejemplos

**Almacenar valores durante periodos de 4 segundos**

[StackBlitz](https://stackblitz.com/edit/rxjs-bufferwhen-1?file=index.ts)

```javascript
import { bufferWhen } from "rxjs/operators";
import { interval } from "rxjs";

const number$ = interval(1000);

number$.pipe(bufferWhen(() => interval(4000))).subscribe(console.log);
// Salida: [0, 1, 2], [3, 4, 5, 6], [7, 8, 9, 10]...
```

**Almacenar valores hasta que se haga click**

[StackBlitz](https://stackblitz.com/edit/rxjs-bufferwhen-2?file=index.ts)

```javascript
import { bufferWhen } from "rxjs/operators";
import { interval, fromEvent } from "rxjs";

const number$ = interval(1000);
const click$ = fromEvent < MouseEvent > (document, "click");

number$.pipe(bufferWhen(() => click$)).subscribe(console.log);
// Salida: (click ) [0, 1, 2, 3, 4] (click) [5, 6]...
```

### Ejemplos de la documentación oficial

**Emite un array de clicks cada \[1-5] segundos**

```javascript
import { fromEvent, interval } from "rxjs";
import { bufferWhen } from "rxjs/operators";

const clicks = fromEvent(document, "click");
const buffered = clicks.pipe(
  bufferWhen(() => interval(1000 + Math.random() * 4000))
);
buffered.subscribe((x) => console.log(x));
```

### Recursos adicionales

[![Source code](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/transformation/assets/icons/source-code.png)](https://github.com/ReactiveX/rxjs/blob/master/src/internal/operators/bufferWhen.ts)

[Documentación oficial en inglés](https://rxjs.dev/api/operators/bufferWhen)


# concatMap

Proyecta cada valor emitido por la fuente a un Observable interno que se une al Observable resultante secuencialmente, esperando a que cada Observable interno esté completo antes de unir el siguiente

💡 Se debe utilizar `concatMap` si se quiere esperar a que cada Observable interno esté completo antes de suscribirse al siguiente

<details>

<summary>Signatura</summary>

#### Firma

`concatMap<T, R, O extends ObservableInput<any>>(project: (value: T, index: number) => O, resultSelector?: (outerValue: T, innerValue: ObservedValueOf<O>, outerIndex: number, innerIndex: number) => R): OperatorFunction<T, ObservedValueOf<O> | R>`

#### Parámetros

#### Retorna

`OperatorFunction<T, ObservedValueOf<O> | R>`: Un Observable que emite el resultado de aplicar la función de proyección (y el `resultSelector` opcional que está obsoleto) a cada elemento emitido por el Observable fuente y obtener los valores de cada Observable interno proyectado de forma secuencial.

</details>

## Descripción

Proyecta cada valor a un Observable interno, que posteriormente 'aplasta' usando el operador `concatAll`.

![Diagrama de canicas del operador concatMap](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/transformation/assets/images/marble-diagrams/transformation/concatMap.png)

Retorna un Observable que emite elementos según el resultado de aplicar una función a cada elemento emitido por el Observable fuente, donde dicha función retorna un Observable interno. Cada nuevo Observable interno se concatena con el Observable interno previo.

Advertencia: Si los valores de la fuente se emiten de forma ilimitada, y más rápidamente de lo que sus Observable internos correspondientes pueden completarse, habrá problemas de memoria, ya que los Observables internos se acumularán en un búfer ilimitado esperando que llegue se turno de ser suscritos.

Nota: `concatMap` es equivalente a utilizar `mergeMap`, teniendo el parámetro de concurrencia el valor 1.

## Ejemplos

**Realizar varias peticiones AJAX de forma secuencial. Hasta que cada petición no termine, no se realizará la siguiente**

[StackBlitz](https://stackblitz.com/edit/rxjs-concatmap-1?file=index.ts)

```javascript
import { concatMap, map } from "rxjs/operators";
import { of } from "rxjs";
import { ajax } from "rxjs/ajax";

const pokemonId$ = of(1, 5, 6);

function getPokemonName(id: number) {
  return ajax
    .getJSON(`https://pokeapi.co/api/v2/pokemon/${id}`)
    .pipe(map(({ name }) => name));
}

pokemonId$.pipe(concatMap((id) => getPokemonName(id))).subscribe(console.log);
// Salida: bulbasaur, charmeleon, charizard
```

**Comparación entre mergeMap y concatMap**

concatMap esperará a que cada petición esté completa antes de realizar la siguiente. Esto implica que todas las peticiones se llevarán a cabo de forma consecutiva.

mergeMap no esparará a que cada petición esté completa, sino que las realizará en paralelo. Esto implica que las peticiones NO se llevarán a cabo de forma consecutiva.

[StackBlitz](https://stackblitz.com/edit/rxjs-concatmap-2?file=index.ts)

```javascript
import { concatMap, mergeMap, map, delayWhen } from "rxjs/operators";
import { of, interval } from "rxjs";
import { ajax } from "rxjs/ajax";

const pokemonId$ = of(1, 5, 6);

function getRandomNumber() {
  return Math.floor(Math.random() * 5) + 1;
}

function getPokemonName(id: number) {
  return ajax.getJSON(`https://pokeapi.co/api/v2/pokemon/${id}`).pipe(
    map(({ name }) => name),
    // El resultado de cada petición se retrasará por un periodo aleatorio de tiempo. Esto se hace para poder observar que, al utilizar mergeMap, los resultados de las peticiones se emitirán en un orden aleatorio
    delayWhen((_) => interval(getRandomNumber() * 1000))
  );
}

pokemonId$.pipe(concatMap((id) => getPokemonName(id))).subscribe(console.log);
// Salida: bulbasaur, charmeleon, charizard

// Con mergeMap, el orden de los resultados será aleatorio
pokemonId$.pipe(mergeMap((id) => getPokemonName(id))).subscribe(console.log);
// Salida: charmeleon, bulbasaur, charizard
```

### Ejemplo de la documentación oficial

**Para cada evento click, emitir los valores de 0 a 3 a intervalos de 1 segundo, sin concurrencia**

```javascript
import { fromEvent, interval } from "rxjs";
import { concatMap, take } from "rxjs/operators";

const clicks = fromEvent(document, "click");
const result = clicks.pipe(concatMap((ev) => interval(1000).pipe(take(4))));
result.subscribe((x) => console.log(x));

// Resulta en:
// (los resultados no son concurrentes)
// Por cada click en el documento, se emitirán los valores del 0 al 3 a intervales de 1000ms
// (click) = 1000ms-> 0 -1000ms-> 1 -1000ms-> 2 -1000ms-> 3
```

<details>

<summary>Sobrecargas</summary>

#### Firma

`concatMap(project: (value: T, index: number) => O): OperatorFunction<T, ObservedValueOf<O>>`

#### Parámetros

#### Retorna

`OperatorFunction<T, ObservedValueOf<O>>`

#### Firma

`concatMap(project: (value: T, index: number) => O, resultSelector: undefined): OperatorFunction<T, ObservedValueOf<O>>`

#### Parámetros

#### Retorna

`OperatorFunction<T, ObservedValueOf<O>>`

#### Firma

`concatMap(project: (value: T, index: number) => O, resultSelector: (outerValue: T, innerValue: ObservedValueOf<O>, outerIndex: number, innerIndex: number) => R): OperatorFunction<T, R>`

#### Parámetros

#### Retorna

`OperatorFunction<T, R>`

</details>

### Recursos adicionales

[![Source code](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/transformation/assets/icons/source-code.png)](https://github.com/ReactiveX/rxjs/blob/master/src/internal/operators/concatMap.ts)

[Documentación oficial en inglés](https://rxjs.dev/api/operators/concatMap)


# concatMapTo

Proyecta cada valor emitido por la fuente al mismo Observable interno, que se une al Observable resultante de forma secuencial

💡 `concatMapTo` siempre utiliza el mismo Observable interno, sin tener en cuenta el valor emitido por la fuente. Si se quiere tener en cuenta el valor emitido, se debe utilizar `concatMap`

<details>

<summary>Signatura</summary>

#### Firma

`concatMapTo<T, R, O extends ObservableInput<any>>(innerObservable: O, resultSelector?: (outerValue: T, innerValue: ObservedValueOf<O>, outerIndex: number, innerIndex: number) => R): OperatorFunction<T, ObservedValueOf<O> | R>`

#### Parámetros

#### Retorna

`OperatorFunction<T, ObservedValueOf<O> | R>`: Un Observable de valores obtenido a partir de fusionar el Observable consigo mismo, una vez por cada valor emitido por la fuente.

</details>

## Descripción

Es como `concatMap`, pero siempre proyecta cada valor al mismo Observable interno.

![Diagrama de canicas del operador concatMapTo](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/transformation/assets/images/marble-diagrams/transformation/concatMapTo.png)

Proyecta cada elemento emitido por la fuente al Observable `innerObservable` proporcionado, independientemente del valor del elemento, y después 'aplana' los Observables internos resultantes en un solo Observable. Cada instancia de Observable interno emitida en el Observable resultante se concatena con la instancia del Observable interno previa.

Advertencia: Si los valores de la fuente se emiten de forma ilimitada, y más rápidamente de lo que sus Observable internos correspondientes pueden completarse, habrá problemas de memoria, ya que los Observables internos se acumularán en un búfer ilimitado esperando que llegue se turno de ser suscritos.

💡 `concatMapTo` es equivalente a `mergeMapTo` con un parámetro de concurrencia de valor 1.

## Ejemplos

**Proyectar cada click al mismo Observable interno, que emite un mensaje**

[StackBlitz](https://stackblitz.com/edit/rxjs-concatmapto-1?file=index.ts)

```javascript
import { fromEvent, of } from "rxjs";
import { concatMapTo } from "rxjs/operators";

const click$ = fromEvent < MouseEvent > (document, "click");

click$.pipe(concatMapTo(of("Hola, has hecho click :D"))).subscribe(console.log);
// Salida: (click) 'Hola, has hecho click :D' (click) 'Hola, has hecho click :D'...
```

**Cada 3 segundos, obtener los títulos de las 3 primeras películas de Ghibli**

[StackBlitz](https://stackblitz.com/edit/rxjs-concatmapto-2?file=index.ts)

```javascript
import { concatMapTo, map, mergeAll, take } from "rxjs/operators";
import { interval } from "rxjs";
import { ajax } from "rxjs/ajax";

const second$ = interval(3000).pipe(take(5));

function getGhibliFilmTitles() {
  return ajax.getJSON(`https://ghibliapi.herokuapp.com/films/`).pipe(
    mergeAll(),
    map(({ title }) => title),
    take(3)
  );
}

second$.pipe(concatMapTo(getGhibliFilmTitles())).subscribe(console.log);
// Salida: Castle in the Sky, Grave of the Fireflies, My Neighbor Totoro
```

### Ejemplo de la documentación oficial

Para cada evento click, emitir los valores de 0 a 3 a intervalos de 1 segundo, sin concurrencia

```javascript
import { fromEvent, interval } from "rxjs";
import { concatMapTo, take } from "rxjs/operators";

const clicks = fromEvent(document, "click");
const result = clicks.pipe(concatMapTo(interval(1000).pipe(take(4))));
result.subscribe((x) => console.log(x));

// Resulta en:
// (los resultados no son concurrentes)
// Por cada click en el documento, se emitirán los valores del 0 al 3 a intervales de 1000ms
// (click) = 1000ms-> 0 -1000ms-> 1 -1000ms-> 2 -1000ms-> 3
```

<details>

<summary>Sobrecargas</summary>

#### Firma

`concatMapTo(observable: O): OperatorFunction<T, ObservedValueOf<O>>`

#### Parámetros

#### Retorna

`OperatorFunction<T, ObservedValueOf<O>>`

#### Firma

`concatMapTo(observable: O, resultSelector: undefined): OperatorFunction<T, ObservedValueOf<O>>`

#### Parámetros

#### Retorna

`OperatorFunction<T, ObservedValueOf<O>>`

#### Firma

`concatMapTo(observable: O, resultSelector: (outerValue: T, innerValue: ObservedValueOf<O>, outerIndex: number, innerIndex: number) => R): OperatorFunction<T, R>`

#### Parámetros

#### Retorna

`OperatorFunction<T, R>`

</details>

### Recursos adicionales

[![Source code](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/transformation/assets/icons/source-code.png)](https://github.com/ReactiveX/rxjs/blob/master/src/internal/operators/concatMapTo.ts)

[Documentación oficial en inglés](https://rxjs.dev/api/operators/concatMapTo)


# exhaust

Convierte un Observable de orden superior a uno de primer orden ignorando los Observables internos mientras el Observable interno actual no se haya completado

<details>

<summary>Signatura</summary>

#### Firma

`exhaust<T>(): OperatorFunction<any, T>`

#### Parámetros

No recibe ningún parámetro.

#### Retorna

`OperatorFunction<any, T>`: Un Observable que recibe una fuente de Observables y propaga el primer Observable hasta que este se completa, antes de suscribirse al siguiente Observable.

</details>

## Descripción

'Aplasta' un Observable de Observables ignorando los Observables internos posteriores mientras el Observable interno actual se esté ejecutando.

![Diagrama de canicas del operador exhaust](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/transformation/assets/images/marble-diagrams/transformation/exhaust.png)

`exhaust` se suscribe a un Observable que emite Observables, también conocido como un Observable de orden superior. Cada vez que observa uno de los Observables internos emitidos, el Observable resultante comienza a emitir los elementos emitidos por dicho Observable interno. Hasta aquí, se comporta igual que `mergeAll`. Sin embargo, `exhaust` ignora todos los Observables internos que se emitan mientras el Observable actual no se haya completado. Una vez que el Observable actual se haya completado, `exhaust` lo unirá al Observable resultante y se suscribirá al siguiente Observable interno y repetirá el proceso.

## Ejemplos

**Obtener 3 películas de Studio Ghibli al hacer click en el botón**

Si hay alguna petición en curso, los clicks serán ignorados (cada petición tiene un retraso de 5s para poder observar este efecto.)

[StackBlitz](https://stackblitz.com/edit/rxjs-exhaust-2?file=index.ts)

```javascript
import { delay, exhaust, map, mergeAll, take } from "rxjs/operators";
import { fromEvent } from "rxjs";
import { ajax } from "rxjs/ajax";

const click$ = fromEvent(document.getElementById("ghibliButton"), "click");

function getGhibliFilms() {
  return ajax.getJSON("https://ghibliapi.herokuapp.com/films").pipe(
    delay(5000),
    mergeAll(),
    map(({ title }) => title),
    take(3)
  );
}

click$
  .pipe(
    map((_) => getGhibliFilms()),
    exhaust()
  )
  .subscribe(console.log);
// Salida: (Primer click) (click ignorado) (click ignorado) (5s) Castle in the Sky, Grave of the Fireflies, My Neighbor Totoro
```

### Ejemplo de la documentación oficial

**Ejecuta un temporizador con cada click, únicamente si no hay ningún temporizador activo**

```javascript
import { fromEvent, interval } from "rxjs";
import { exhaust, map, take } from "rxjs/operators";

const clicks = fromEvent(document, "click");
const higherOrder = clicks.pipe(map((ev) => interval(1000).pipe(take(5))));
const result = higherOrder.pipe(exhaust());
result.subscribe((x) => console.log(x));
```

### Recursos adicionales

[![Source code](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/transformation/assets/icons/source-code.png)](https://github.com/ReactiveX/rxjs/blob/master/src/internal/operators/exhaust.ts)

[Documentación oficial en inglés](https://rxjs.dev/api/operators/exhaust)


# exhaustMap

Proyecta cada emisión de la fuente a un Observable interno que se fusiona con el Observable resultante únicamente si el Observable interno anterior se ha completado

💡 Se debe utilizar `exhaustMap` si se quiere ignorar los Observables internos mientras no se haya completado el Observable interno anterior

<details>

<summary>Signatura</summary>

#### Firma

`exhaustMap<T, R, O extends ObservableInput<any>>(project: (value: T, index: number) => O, resultSelector?: (outerValue: T, innerValue: ObservedValueOf<O>, outerIndex: number, innerIndex: number) => R): OperatorFunction<T, ObservedValueOf<O> | R>`

#### Parámetros

#### Retorna

`OperatorFunction<T, ObservedValueOf<O> | R>`: Un Observable que contiene Observables proyectados de cada elemento de la fuente. Ignora los Observables proyectados que comiencen antes de que el Observable proyectado actual se haya completado.

</details>

## Descripción

Proyecta cada valor a un Observable interno, y 'aplasta' todos estos Observables internos mediante el operador `exhaust`.

![Diagrama de canicas del operador exhaustMap](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/transformation/assets/images/marble-diagrams/transformation/exhaustMap.png)

Retorna un Observable que aplica una función a cada uno de los elementos emitidos por el Observable fuente, donde dicha función retorna un Observable interno. Cuando se proyecta cada elemento de la fuente a un Observable, el Observable resultante comienza a emitir los elementos emitidos por el Observable interno. Sin embargo, `exhaustMap` ignora todos los Observables internos nuevos si el Observable interno anterior no se ha completado. Una vez se complete, `exhaustMap` se suscribirá y 'aplastará' el siguiente Observable interno y repetirá el proceso.

## Ejemplos

**Obtener 3 películas de Studio Ghibli al hacer click en el botón**

Si hay alguna petición en curso, los clicks serán ignorados (cada petición tiene un retraso de 5s para poder observar este efecto.)

[StackBlitz](https://stackblitz.com/edit/rxjs-exhaustmap-1?file=index.ts)

```typescript
import { delay, exhaustMap, map, mergeAll, take } from "rxjs/operators";
import { fromEvent } from "rxjs";
import { ajax } from "rxjs/ajax";

const click$ = fromEvent(document.getElementById("ghibliButton"), "click");

function getGhibliFilms() {
  return ajax.getJSON("https://ghibliapi.herokuapp.com/films").pipe(
    delay(5000),
    mergeAll(),
    map(({ title }) => title),
    take(3)
  );
}

// Obtener 3 películas de Studio Ghibli al hacer click en el botón. Si hay alguna petición en curso, los clicks serán ignorados (cada petición tiene un retraso de 5s para poder observar este efecto.)
click$.pipe(exhaustMap((_) => getGhibliFilms())).subscribe(console.log);
// Salida: (Primer click) (click ignorado) (click ignorado) (5s) Castle in the Sky, Grave of the Fireflies, My Neighbor Totoro
```

### Ejemplo de la documentación oficial

**Ejecuta un temporizador con cada click, únicamente si no hay ningún temporizador activo**

```javascript
import { fromEvent, interval } from "rxjs";
import { exhaustMap, take } from "rxjs/operators";

const clicks = fromEvent(document, "click");
const result = clicks.pipe(exhaustMap((ev) => interval(1000).pipe(take(5))));
result.subscribe((x) => console.log(x));
```

<details>

<summary>Sobrecargas</summary>

#### Firma

`exhaustMap(project: (value: T, index: number) => O): OperatorFunction<T, ObservedValueOf<O>>`

#### Parámetros

#### Retorna

`OperatorFunction<T, ObservedValueOf<O>>`

#### Firma

`exhaustMap(project: (value: T, index: number) => O, resultSelector: undefined): OperatorFunction<T, ObservedValueOf<O>>`

#### Parámetros

#### Retorna

`OperatorFunction<T, ObservedValueOf<O>>`

#### Firma

`exhaustMap(project: (value: T, index: number) => any, resultSelector: (outerValue: T, innerValue: I, outerIndex: number, innerIndex: number) => R): OperatorFunction<T, R>`

#### Parámetros

#### Retorna

`OperatorFunction<T, R>`

</details>

### Recursos adicionales

[![Source code](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/transformation/assets/icons/source-code.png)](https://github.com/ReactiveX/rxjs/blob/master/src/internal/operators/exhaustMap.ts)

[Documentación oficial en inglés](https://rxjs.dev/api/operators/exhaustMap)


# expand

Proyecta recursivamente cada valor de la fuente a un Observable que se fusiona con el Observable resultante

<details>

<summary>Signatura</summary>

#### Firma

`expand<T, R>(project: (value: T, index: number) => any, concurrent: number = Number.POSITIVE_INFINITY, scheduler: SchedulerLike = undefined): OperatorFunction<T, R>`

#### Parámetros

#### Retorna

`OperatorFunction<T, R>`: Un Observable que emite los valores de la fuente. También emite el resultado de aplicar la función de proyeccón a cada valor emitido en el Observable de salida, fusionando los Observables obtenidos de esta transformación.

</details>

## Descripción

Es similar a `mergeMap`, pero aplica la función de proyección a cada valor de la fuente además de a cada valor de salida. Es recursivo.

![Diagrama de canicas del operador expand](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/transformation/assets/images/marble-diagrams/transformation/expand.png)

Retorna un Observable que aplica una función a cada elemento emitido por el Observable fuente, donde dicha función retorna otro Observable, y fusiona los Observables resultantes, emitiendo el resultado de esta fusión. expand reemitirá cada valor de la fuente en el Observable resultante.

Entonces, cada valor de salida se le proporciona a la función de proyección, que retorna un Observable interno que se fusiona en el Observable resultante. Esos valores de salida resultantes de la proyección también se le proporcionan a la función project para producir nuevos valores de salida. Así es como expand se comporta de forma recursiva.

## Ejemplos

**Obtener los 3 números consecutivos a un número**

[StackBlitz](https://stackblitz.com/edit/rxjs-expand-1?file=index.ts)

```javascript
import { of } from "rxjs";
import { expand, take } from "rxjs/operators";

const number$ = of(1);

number$
  .pipe(
    expand((val) => of(val + 1)),
    take(4)
  )
  .subscribe(console.log);
// Salida: 1, 2, 3, 4
```

**Obtener una secuencia geométrica multiplicando el número introducido por dos**

[StackBlitz](https://stackblitz.com/edit/rxjs-expand-2?file=index.ts)

```typescript
import { fromEvent, of } from "rxjs";
import { debounceTime, expand, map, take, repeat } from "rxjs/operators";

const numberInput = document.getElementById("number");

const number$ = fromEvent(numberInput, "keyup").pipe(
  map((event) => +(<HTMLInputElement>event.target).value)
);

number$
  .pipe(
    debounceTime(300),
    expand((val) => of(val * 2)),
    take(4),
    repeat()
  )
  .subscribe(console.log);
// Salida: (introducir nº 2) 2, 4, 8, 16
```

### Ejemplo de la documentación oficial

**Comienza a emitir como mucho diez potencias de dos, por cada click**

```javascript
import { fromEvent, of } from "rxjs";
import { expand, mapTo, delay, take } from "rxjs/operators";

const clicks = fromEvent(document, "click");
const powersOfTwo = clicks.pipe(
  mapTo(1),
  expand((x) => of(2 * x).pipe(delay(1000))),
  take(10)
);
powersOfTwo.subscribe((x) => console.log(x));
```

### Recursos adicionales

[![Source code](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/transformation/assets/icons/source-code.png)](https://github.com/ReactiveX/rxjs/blob/master/src/internal/operators/expand.ts)

[Documentación oficial en inglés](https://rxjs.dev/api/operators/expand)


# groupBy

Agrupa los elementos emitidos por un Observable según un criterio especificado, y emite estas agrupaciones como GroupedObservables, con un GroupedObservable por cada grupo

<details>

<summary>Signatura</summary>

#### Firma

`groupBy<T, K, R>(keySelector: (value: T) => K, elementSelector?: void | ((value: T) => R), durationSelector?: (grouped: GroupedObservable<K, R>) => Observable<any>, subjectSelector?: () => Subject<R>): OperatorFunction<T, GroupedObservable<K, R>>`

#### Parámetros

#### Retorna

`OperatorFunction<T, GroupedObservable<K, R>>`: Un Observable que emite `GroupedObservables`, cada uno de los cuales pertenece a un único valor clave. Cada grupo emite los elementos del Observable que comparten el mismo valor clave.

</details>

## Descripción

![Diagrama de canicas del operador groupBy](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/transformation/assets/images/marble-diagrams/transformation/groupBy.png)

Cuando el Observable emite un elemento, se computa una clave para dicho elemento mediante la función `keySelector`.

Si existe un GroupedObservable para dicha clave, el GroupedObservable emite. Si no existe, se crea un GroupedObservable para dicha clave y emite.

Un GroupedObservable representa valores que pertenecen al mismo grupo, representado por una clave. La clave está disponible como el campo key de una instancia GroupedObservable.

Los elementos emitidos por GroupedObservables son, por defecto, los elementos emitidos por el Observable, o los elementos retornados por la función elementSelector.

## Ejemplos

**Agrupar lenguajes de programación según su tipo, y emitir el GroupedObservable resultante en forma de array**

[StackBlitz](https://stackblitz.com/edit/rxjs-groupby-1?file=index.ts)

```javascript
import { groupBy, mergeMap, toArray } from "rxjs/operators";
import { from } from "rxjs";

const language$ = from([
  { name: "Rust", type: "Multiparadigma" },
  { name: "Java", type: "Orientado a objetos" },
  { name: "Scala", type: "Multiparadigma" },
  { name: "Simula", type: "Orientado a objetos" },
  { name: "Haskell", type: "Funcional" },
]);

language$
  .pipe(
    groupBy(({ type }) => type),
    mergeMap((group$) => group$.pipe(toArray()))
  )
  .subscribe(console.log);
/* Salida: 
[{ name: "Rust", type: "Multiparadigma" }, { name: "Scala", type: "Multiparadigma" }],
[{ name: "Java", type: "Orientado a objetos" }, { name: "Simula", type: "Orientado a objetos" }],
[{ name: "Haskell", type: "Funcional" }]
*/
```

**Agrupar lenguajes de programación según su tipo, seleccionar únicamente el nombre y emitir el GroupedObservable resultante en forma de array**

[StackBlitz](https://stackblitz.com/edit/rxjs-groupby-2?file=index.ts)

```javascript
import { groupBy, mergeMap, toArray } from "rxjs/operators";
import { from } from "rxjs";

const language$ = from([
  { name: "Rust", type: "Multiparadigma" },
  { name: "Java", type: "Orientado a objetos" },
  { name: "Scala", type: "Multiparadigma" },
  { name: "Simula", type: "Orientado a objetos" },
  { name: "Haskell", type: "Funcional" },
]);

language$
  .pipe(
    groupBy(
      ({ type }) => type,
      ({ name }) => name
    ),
    mergeMap((group$) => group$.pipe(toArray()))
  )
  .subscribe(console.log);
/* Salida:
  ["Rust", "Scala"],
  ["Java", "Simula"],,
  ["Haskell"]
*/
```

### Ejemplo de la documentación oficial

**Agrupar objetos por id y retornar las agrupaciones como arrays**

```javascript
import { of } from "rxjs";
import { mergeMap, groupBy, reduce } from "rxjs/operators";

of(
  { id: 1, name: "JavaScript" },
  { id: 2, name: "Parcel" },
  { id: 2, name: "webpack" },
  { id: 1, name: "TypeScript" },
  { id: 3, name: "TSLint" }
)
  .pipe(
    groupBy((p) => p.id),
    mergeMap((group$) => group$.pipe(reduce((acc, cur) => [...acc, cur], [])))
  )
  .subscribe((p) => console.log(p));

// Salida:
// [ { id: 1, name: 'JavaScript'},
//   { id: 1, name: 'TypeScript'} ]
//
// [ { id: 2, name: 'Parcel'},
//   { id: 2, name: 'webpack'} ]
//
// [ { id: 3, name: 'TSLint'} ]
```

**Pivotar los datos por el campo id**

```javascript
import { of } from "rxjs";
import { groupBy, map, mergeMap, reduce } from "rxjs/operators";

of(
  { id: 1, name: "JavaScript" },
  { id: 2, name: "Parcel" },
  { id: 2, name: "webpack" },
  { id: 1, name: "TypeScript" },
  { id: 3, name: "TSLint" }
)
  .pipe(
    groupBy(
      (p) => p.id,
      (p) => p.name
    ),
    mergeMap((group$) =>
      group$.pipe(reduce((acc, cur) => [...acc, cur], [`${group$.key}`]))
    ),
    map((arr) => ({ id: parseInt(arr[0], 10), values: arr.slice(1) }))
  )
  .subscribe((p) => console.log(p));

// Salida:
// { id: 1, values: [ 'JavaScript', 'TypeScript' ] }
// { id: 2, values: [ 'Parcel', 'webpack' ] }
// { id: 3, values: [ 'TSLint' ] }
```

<details>

<summary>Sobrecargas</summary>

#### Firma

`groupBy(keySelector: (value: T) => K): OperatorFunction<T, GroupedObservable<K, T>>`

#### Parámetros

#### Retorna

`OperatorFunction<T, GroupedObservable<K, T>>`

#### Firma

`groupBy(keySelector: (value: T) => K, elementSelector: void, durationSelector: (grouped: GroupedObservable<K, T>) => Observable<any>): OperatorFunction<T, GroupedObservable<K, T>>`

#### Parámetros

#### Retorna

`OperatorFunction<T, GroupedObservable<K, T>>`

#### Firma

`groupBy(keySelector: (value: T) => K, elementSelector?: (value: T) => R, durationSelector?: (grouped: GroupedObservable<K, R>) => Observable<any>): OperatorFunction<T, GroupedObservable<K, R>>`

#### Parámetros

#### Retorna

`OperatorFunction<T, GroupedObservable<K, R>>`

#### Firma

`groupBy(keySelector: (value: T) => K, elementSelector?: (value: T) => R, durationSelector?: (grouped: GroupedObservable<K, R>) => Observable<any>, subjectSelector?: () => Subject<R>): OperatorFunction<T, GroupedObservable<K, R>>`

#### Parámetros

#### Retorna

`OperatorFunction<T, GroupedObservable<K, R>>`

</details>

### Recursos adicionales

[![Source code](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/transformation/assets/icons/source-code.png)](https://github.com/ReactiveX/rxjs/blob/master/src/internal/operators/groupBy.ts)

[Documentación oficial en inglés](https://rxjs.dev/api/operators/groupBy)


# map

Aplica una función de proyección a cada valor emitido por el Observable fuente, y emite los valores resultantes como un Observable

<details>

<summary>Signatura</summary>

#### Firma

`map<T, R>(project: (value: T, index: number) => R, thisArg?: any): OperatorFunction<T, R>`

#### Parámetros

#### Retorna

`OperatorFunction<T, R>`: Un Observable que emite los valores del Observable fuente transformados por la función de proyección.

</details>

## Descripción

Al igual que `Array.prototype.map()`, aplica una función de transformación a cada uno de los valores emitidos por la fuente, para obtener los valores de salida correspondientes.

![Diagrama de canicas del operador map](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/transformation/assets/images/marble-diagrams/transformation/map.png)

Al igual que la función `Array.prototype.map`, este operador aplica una función de proyección a cada valor y emite dicha proyección en el Observable resultante.

## Ejemplos

**Multiplicar cada número por 2**

[StackBlitz](https://stackblitz.com/edit/rxjs-map-1?file=index.ts)

```javascript
import { map } from "rxjs/operators";
import { fromEvent, range } from "rxjs";

const number$ = range(1, 5);

number$.pipe(map((number) => number * 2)).subscribe(console.log);
// Salida: 2, 4, 6, 8, 10
```

**Emitir la propiedad code de cada objeto KeyboardEvent**

[StackBlitz](https://stackblitz.com/edit/rxjs-map-2?file=index.ts)

```typescript
import { map } from "rxjs/operators";
import { fromEvent } from "rxjs";

const key$ = fromEvent<KeyboardEvent>(document, "keydown");

key$.pipe(map(({ code }) => code)).subscribe(console.log);
// Salida: KeyX, KeyO...
```

### Ejemplos de la documentación oficial

**Proyecta cada click a la posición clientX de dicho click**

```javascript
import { fromEvent } from "rxjs";
import { map } from "rxjs/operators";

const clicks = fromEvent(document, "click");
const positions = clicks.pipe(map((ev) => ev.clientX));
positions.subscribe((x) => console.log(x));
```

### Recursos adicionales

[![Source code](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/transformation/assets/icons/source-code.png)](https://github.com/ReactiveX/rxjs/blob/master/src/internal/operators/map.ts)

[Documentación oficial en inglés](https://rxjs.dev/api/operators/map)


# mapTo

Emite el mismo valor cada vez que el Observable fuente emite un valor

<details>

<summary>Signatura</summary>

#### Firma

`mapTo<T, R>(value: R): OperatorFunction<T, R>`

#### Parámetros

#### Retorna

`OperatorFunction<T, R>`: Un Observable que emite el mismo valor cada vez que el Observable fuente emite algo.

</details>

## Descripción

Es como `map`, pero proyecta cada emisión siempre al mismo valor.

![Diagrama de canicas del operador mapTo](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/transformation/assets/images/marble-diagrams/transformation/mapTo.png)

Recibe un valor constante como argumento, que emite cuandoquiera que el Observable fuente emita un valor. En otras palabras, ignora el valor emitido, y simplemente utiliza el momento de emisión para saber cuándo emitir el valor constante proporcionado.

## Ejemplos

**Emitir "La respuesta es 42" de forma indefinida**

[StackBlitz](https://stackblitz.com/edit/rxjs-mapto-1?file=index.ts)

```javascript
import { mapTo } from "rxjs/operators";
import { interval } from "rxjs";

const number$ = interval(1000);

number$.pipe(mapTo("La respuesta es 42")).subscribe(console.log);
// Salida: La respuesta es 42, La respuesta es 42, La respuesta es 42, La respuesta es 42...
```

**Emitir "¡Tecla pulsada!" cada vez que se pulse una tecla**

[StackBlitz](https://stackblitz.com/edit/rxjs-mapto-2?file=index.ts)

```javascript
import { mapTo } from "rxjs/operators";
import { fromEvent } from "rxjs";

const key$ = fromEvent(document, "keydown");

key$.pipe(mapTo("¡Tecla pulsada!")).subscribe(console.log);
// Salida: (keyPress) ¡Tecla pulsada!...
```

### Ejemplo de la documentación oficial

**Proyectar cada click a la cadena 'Hi'**

```javascript
import { fromEvent } from "rxjs";
import { mapTo } from "rxjs/operators";

const clicks = fromEvent(document, "click");
const greetings = clicks.pipe(mapTo("Hi"));
greetings.subscribe((x) => console.log(x));
```

### Recursos adicionales

[![Source code](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/transformation/assets/icons/source-code.png)](https://github.com/ReactiveX/rxjs/blob/master/src/internal/operators/mapTo.ts)

[Documentación oficial en inglés](https://rxjs.dev/api/operators/mapTo)


# mergeMap

Proyecta cada valor emitido por la fuente a un Observable que se fusiona en el Observable resultante

💡 Se debe utilizar `mergeMap` si se quieren tener varios Observables internos suscritos de forma concurrente

<details>

<summary>Signatura</summary>

#### Firma

`mergeMap<T, R, O extends ObservableInput<any>>(project: (value: T, index: number) => O, resultSelector?: number | ((outerValue: T, innerValue: ObservedValueOf<O>, outerIndex: number, innerIndex: number) => R), concurrent: number = Number.POSITIVE_INFINITY): OperatorFunction<T, ObservedValueOf<O> | R>`

#### Parámetros

#### Retorna

`OperatorFunction<T, ObservedValueOf<O> | R>`: Un Observable que emite el resultado de aplicar la función de proyección ( y el ya obsoleto `resultSelector` opcional) a cada elemento emitido por el Observable fuente y fusionando los resultados de los Observables obtenidos a partir de esta transformación.

</details>

## Descripción

Proyecta cada valor a un Observable interno, y 'aplasta' cada uno de estos Observables internos mediante el operador `mergeAll`.

![Diagrama de canicas del operador mergeMap](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/transformation/assets/images/marble-diagrams/transformation/mergeMap.png)

Retorna un Observable que, después de aplicar una función a cada elemento emitido por el Observable fuente, donde dicha función retorna un Observable, fusiona los Observables internos resultantes y emite el resultado de la fusión.

## Ejemplos

Como mergeMap se suscribe a los Observables internos de forma concurrente, y se le ha añadido un retardo aleatorio a las peticiones AJAX, se puede observar que // TODO

[StackBlitz](https://stackblitz.com/edit/rxjs-mergemap-1?file=index.ts)

```javascript
import { mergeMap, map, tap, delayWhen } from "rxjs/operators";
import { interval, of } from "rxjs";
import { ajax } from "rxjs/ajax";

function getRandomNumber() {
  return Math.floor(Math.random() * 100) + 20;
}

const pokemonId$ = of(1, 4, 7);

function getPokemonName(id: number) {
  return ajax.getJSON(`https://pokeapi.co/api/v2/pokemon/${id}`).pipe(
    map(({ name, id }) => ({ name, id })),
    // Añadimos un retardo aleatorio a cada petición, para poder observar el efecto de mergeMap
    delayWhen((_) => interval(getRandomNumber() * 100))
  );
}

pokemonId$
  .pipe(
    tap((number) => console.log(`Obteniendo Pokémon con id: ${number}`)),
    mergeMap((number) => getPokemonName(number))
  )
  .subscribe(console.log);
/* Output: 
    Obteniendo Pokémon con id: 1, 
    Obteniendo Pokémon con id: 4, 
    Obteniendo Pokémon con id: 7,
    { name: "Squirtle", id: 7 },
    { name: "Bulbasaur", id: 1 },
    { name: "Charmander", id: 4 }
*/
```

### Ejemplo de la documentación oficial

**Proyectar y 'aplastar' cada letra a un Observable que emite cada segundo**

```javascript
import { of, interval } from "rxjs";
import { mergeMap, map } from "rxjs/operators";

const letters = of("a", "b", "c");
const result = letters.pipe(
  mergeMap((x) => interval(1000).pipe(map((i) => x + i)))
);
result.subscribe((x) => console.log(x));

// Salida:
// a0
// b0
// c0
// a1
// b1
// c1
// continúa listando a,b,c con un el número ascendiente que corresponda
```

<details>

<summary>Sobrecargas</summary>

#### Firma

`mergeMap(project: (value: T, index: number) => O, concurrent?: number): OperatorFunction<T, ObservedValueOf<O>>`

#### Parámetros

#### Retorna

`OperatorFunction<T, ObservedValueOf<O>>`

#### Firma

`mergeMap(project: (value: T, index: number) => O, resultSelector: undefined, concurrent?: number): OperatorFunction<T, ObservedValueOf<O>>`

#### Parámetros

#### Retorna

`OperatorFunction<T, ObservedValueOf<O>>`

#### Firma

`mergeMap(project: (value: T, index: number) => O, resultSelector: (outerValue: T, innerValue: ObservedValueOf<O>, outerIndex: number, innerIndex: number) => R, concurrent?: number): OperatorFunction<T, R>`

#### Parámetros

#### Retorna

`OperatorFunction<T, R>`

</details>

### Recursos adicionales

[![Source code](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/transformation/assets/icons/source-code.png)](https://github.com/ReactiveX/rxjs/blob/master/src/internal/operators/mergeMap.ts)

[Documentación oficial en inglés](https://rxjs.dev/api/operators/mergeMap)


# mergeMapTo

Proyecta cada valor emitido por la fuente al mismo Observable, que se fusiona con el Observable resultante

<details>

<summary>Signatura</summary>

#### Firma

`mergeMapTo<T, R, O extends ObservableInput<any>>(innerObservable: O, resultSelector?: number | ((outerValue: T, innerValue: ObservedValueOf<O>, outerIndex: number, innerIndex: number) => R), concurrent: number = Number.POSITIVE_INFINITY): OperatorFunction<T, ObservedValueOf<O> | R>`

#### Parámetros

Opcional. El valor por defecto es `Number.POSITIVE_INFINITY`. El máximo número de Observables internos a los que se suscribe de forma concurrente.

#### Retorna

`OperatorFunction<T, ObservedValueOf<O> | R>`: Un Observable que emite elementos del Observable `innerObservable` proporcionado.

</details>

## Descripción

Es como `mergeMap`, pero siempre proyecta los valores al mismo Observable interno.

![Diagrama de canicas del operador mergeMapTo](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/transformation/assets/images/marble-diagrams/transformation/mergeMapTo.png)

Proyecta cada emisión de la fuente al Observable `innerObservable` dado, independientemente del valor de dicha emisión, y fusiona los Observables internos resultantes en un solo Observable: el Observable resultante.

## Ejemplos

**Proyectar cada click al mismo Observable interno, que emite un mensaje**

[StackBlitz](https://stackblitz.com/edit/rxjs-mergemapto-1?file=index.ts)

```typescript
import { fromEvent, of } from "rxjs";
import { mergeMapTo } from "rxjs/operators";

const click$ = fromEvent<MouseEvent>(document, "click");

click$.pipe(mergeMapTo(of("Hola, has hecho click :D"))).subscribe(console.log);
// Salida: (click) 'Hola, has hecho click :D' (click) 'Hola, has hecho click :D'...
```

**Cada 3 segundos, obtener los títulos de las 3 primeras películas de Ghibli**

[StackBlitz](https://stackblitz.com/edit/rxjs-mergemapto-2?file=index.ts)

```javascript
import { mergeMapTo, map, mergeAll, take } from "rxjs/operators";
import { interval } from "rxjs";
import { ajax } from "rxjs/ajax";

const second$ = interval(3000).pipe(take(5));

function getGhibliFilmTitles() {
  return ajax.getJSON(`https://ghibliapi.herokuapp.com/films/`).pipe(
    mergeAll(),
    map(({ title }) => title),
    take(3)
  );
}

second$.pipe(mergeMapTo(getGhibliFilmTitles())).subscribe(console.log);
// Salida: (3s) Castle in the Sky, Grave of the Fireflies, My Neighbor Totoro (3s) Castle in the Sky, Grave of the Fireflies, My Neighbor Totoro...
```

### Ejemplo de la documentación oficial

**Por cada evento click, empezar un intervalo Observable de 1 segundo**

```javascript
import { fromEvent, interval } from "rxjs";
import { mergeMapTo } from "rxjs/operators";

const clicks = fromEvent(document, "click");
const result = clicks.pipe(mergeMapTo(interval(1000)));
result.subscribe((x) => console.log(x));
```

### Recursos adicionales

[![Source code](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/transformation/assets/icons/source-code.png)](https://github.com/ReactiveX/rxjs/blob/master/src/internal/operators/mergeMapTo.ts)

[Documentación oficial en inglés](https://rxjs.dev/api/operators/mergeMapTo)


# mergeScan

Aplica una función de acumulación al Observable fuente donde la propia función de acumulación retorna un Observable. Cada Observable interno retornado se fusiona con el Observable resultante

<details>

<summary>Signatura</summary>

#### Firma

`mergeScan<T, R>(accumulator: (acc: R, value: T, index: number) => any, seed: R, concurrent: number = Number.POSITIVE_INFINITY): OperatorFunction<T, R>`

#### Parámetros

#### Retorna

`OperatorFunction<T, R>`: Un Observable de los valores acumulados.

</details>

## Descripción

Es como `scan`, pero los Observables retornados por el acumulador se fusionan en el Observable resultante.

## Ejemplos

**Contar el número de teclas pulsadas**

[StackBlitz](https://stackblitz.com/edit/rxjs-mergescan-1?file=index.ts)

```javascript
import { fromEvent, of } from "rxjs";
import { mapTo, mergeScan } from "rxjs/operators";

const key$ = fromEvent(document, "keydown").pipe(mapTo(1));

key$.pipe(mergeScan((acc, one) => of(acc + one), 0)).subscribe(console.log);
// Salida: (Pulsar tecla) 1, (Pulsar tecla ) 2, (Pulsar tecla) 3...
```

**Acumular el tiempo que esté pulsado el ratón**

[StackBlitz](https://stackblitz.com/edit/rxjs-mergescan-2?file=index.ts)

```javascript
import { fromEvent, interval } from "rxjs";
import { mergeScan, takeUntil, map } from "rxjs/operators";

const mouseDown$ = fromEvent(document, "mousedown");
const mouseUp$ = fromEvent(document, "mouseup");

mouseDown$
  .pipe(
    mergeScan(
      (acc, curr) =>
        interval(1000).pipe(
          takeUntil(mouseUp$),
          map((n) => acc + n)
        ),
      0
    )
  )
  .subscribe(console.log, console.error);
// Salida: (ratón pulsado 5s) 0, 1, 2, 3, 4 (ratón pulsado 2s) 4, 5, 6...
```

### Ejemplo de la documentación oficial

**Contar el número de eventos click**

```javascript
import { fromEvent, of } from "rxjs";
import { mapTo, mergeScan } from "rxjs/operators";

const click$ = fromEvent(document, "click");
const one$ = click$.pipe(mapTo(1));
const seed = 0;
const count$ = one$.pipe(mergeScan((acc, one) => of(acc + one), seed));
count$.subscribe((x) => console.log(x));

// Salida:
// 1
// 2
// 3
// 4
// ...y así sucesivamente para cada click
```

### Recursos adicionales

[![Source code](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/transformation/assets/icons/source-code.png)](https://github.com/ReactiveX/rxjs/blob/master/src/internal/operators/mergeScan.ts)

[Documentación oficial en inglés](https://rxjs.dev/api/operators/mergeScan)


# pairwise

Agrupa las emisiones consecutivas en pares y las emite en forma de array

<details>

<summary>Signatura</summary>

#### Firma

`pairwise<T>(): OperatorFunction<T, [T, T]>`

#### Parámetros

No recibe ningún parámetro.

#### Retorna

`OperatorFunction<T, [T, T]>`: Un Observable de pares (en forma de array) de valores consecutivos del Observable fuente.

</details>

## Descripción

Recoge el valor actual y el anterior en un array, y lo emite.

![Diagrama de canicas del operador pairwise](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/transformation/assets/images/marble-diagrams/transformation/pairwise.png)

La N-ésima emisión del Observable fuente hará que el Observable resultante emita un array \[(N-1)-ésimo, N-ésimo] del valor anterior y del actual. Por esta razón, \`pairwise++ emite a partir de la segunda emisión del Observable fuente, y no a partir de la primera emisión, ya que en ese caso no hay valor previo.

## Ejemplos

**Agrupar la cadena anterior y la actual en un array**

[StackBlitz](https://stackblitz.com/edit/rxjs-pairwise-1?file=index.ts)

```javascript
import { pairwise } from "rxjs/operators";
import { from } from "rxjs";

const framework$ = from(["Angular", "React", "Vue"]);

framework$.pipe(pairwise()).subscribe(console.log);
// Salida: ["Angular", "React"], ["React", "Vue"]
```

**Agrupar los códigos de las teclas pulsadas (a partir de la segunda) por parejas**

[StackBlitz](https://stackblitz.com/edit/rxjs-pairwise-2?file=index.ts)

```typescript
import { fromEvent } from "rxjs";
import { map, pairwise } from "rxjs/operators";

const key$ = fromEvent<KeyboardEvent>(document, "keydown").pipe(
  map(({ code }) => code)
);

key$.pipe(pairwise()).subscribe(console.log);
// Salida: ["KeyR", "KeyX"], ["KeyJ", "KeyS"]...
```

### Ejemplo de la documentación oficial

**En cada click (empezando a partir del segundo), emitir la distancia relativa al click anterior**

```javascript
import { fromEvent } from "rxjs";
import { pairwise, map } from "rxjs/operators";

const clicks = fromEvent(document, "click");
const pairs = clicks.pipe(pairwise());
const distance = pairs.pipe(
  map((pair) => {
    const x0 = pair[0].clientX;
    const y0 = pair[0].clientY;
    const x1 = pair[1].clientX;
    const y1 = pair[1].clientY;
    return Math.sqrt(Math.pow(x0 - x1, 2) + Math.pow(y0 - y1, 2));
  })
);
distance.subscribe((x) => console.log(x));
```

### Recursos adicionales

[![Source code](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/transformation/assets/icons/source-code.png)](https://github.com/ReactiveX/rxjs/blob/master/src/internal/operators/pairwise.ts)

[Documentación oficial en inglés](https://rxjs.dev/api/operators/pairwise)




---

[Next Page](/llms-full.txt/1)

