# Introduction

Clear examples, explanations, and resources for RxJS.

*By* [*@btroncone*](https://twitter.com/BTroncone)

## Introduction

[RxJS](https://github.com/ReactiveX/rxjs) is one of the hottest libraries in web development today. Offering a powerful, functional approach for dealing with events and with integration points into a growing number of frameworks, libraries, and utilities, the case for learning Rx has never been more appealing. Couple this with the ability to utilize your knowledge across [nearly any language](http://reactivex.io/languages.html), having a solid grasp on reactive programming and what it can offer seems like a no-brainer.

**But...**

Learning RxJS and reactive programming is [hard](https://twitter.com/hoss/status/742643506536153088). There's the multitude of concepts, large API surface, and fundamental shift in mindset from an [imperative to declarative style](https://tylermcginnis.com/imperative-vs-declarative-programming/). This site focuses on making these concepts approachable, the examples clear and easy to explore, and features references throughout to the best RxJS related material on the web. The goal is to supplement the [official docs](http://reactivex.io/rxjs/) and pre-existing learning material while offering a new, fresh perspective to clear any hurdles and tackle the pain points. Learning Rx may be difficult but it is certainly worth the effort!

### Brand New to RxJS?

Start getting familiar with all the key concepts needed to be productive with our [RxJS Primer](/learn-rxjs/concepts/rxjs-primer)!

## Content

#### Operators

Operators are the horse-power behind observables, providing an elegant, declarative solution to complex asynchronous tasks. This section contains all [RxJS operators](/learn-rxjs/operators), included with clear, executable examples. Links to additional resources and recipes for each operator are also provided, when applicable.

**Operator Categories**

* [Combination](/learn-rxjs/operators/combination)
* [Conditional](/learn-rxjs/operators/conditional)
* [Creation](/learn-rxjs/operators/creation)
* [Error Handling](/learn-rxjs/operators/error_handling)
* [Multicasting](/learn-rxjs/operators/multicasting)
* [Filtering](/learn-rxjs/operators/filtering)
* [Transformation](/learn-rxjs/operators/transformation)
* [Utility](/learn-rxjs/operators/utility)

**OR...**

[Complete listing in alphabetical order](/learn-rxjs/operators/complete)

#### Understanding Subjects

A Subject is a special type of Observable which shares a single execution path among observers.

* [Overview](/learn-rxjs/subjects)
* [AsyncSubject](/learn-rxjs/subjects/asyncsubject)
* [BehaviorSubject](/learn-rxjs/subjects/behaviorsubject)
* [ReplaySubject](/learn-rxjs/subjects/replaysubject)
* [Subject](/learn-rxjs/subjects/subject)

#### Concepts

Without a solid base knowledge of how Observables work behind the scenes, it's easy for much of RxJS to feel like 'magic'. This section helps solidify the major concepts needed to feel comfortable with reactive programming and Observables.

* [RxJS Primer](/learn-rxjs/concepts/rxjs-primer)
* [Get started transforming streams with map, pluck, and mapTo](/learn-rxjs/concepts/get-started-transforming)
* [Time based operators comparison](/learn-rxjs/concepts/time-based-operators-comparison)
* [RxJS v5 -> v6 Upgrade](/learn-rxjs/concepts/rxjs5-6)

#### Recipes

Recipes for common use-cases and interesting solutions with RxJS.

* [Alphabet Invasion Game](/learn-rxjs/recipes/alphabet-invasion-game)
* [Battleship Game](/learn-rxjs/recipes/battleship-game)
* [Breakout Game](/learn-rxjs/recipes/breakout-game)
* [Car Racing Game](/learn-rxjs/recipes/car-racing-game)
* [Catch The Dot Game](/learn-rxjs/recipes/catch-the-dot-game)
* [Click Ninja Game](/learn-rxjs/recipes/click-ninja-game)
* [Flappy Bird Game](/learn-rxjs/recipes/flappy-bird-game)
* [Game Loop](/learn-rxjs/recipes/gameloop)
* [Horizontal Scroll Indicator](/learn-rxjs/recipes/horizontal-scroll-indicator)
* [HTTP Polling](/learn-rxjs/recipes/http-polling)
* [Lockscreen](/learn-rxjs/recipes/lockscreen)
* [Matrix Digital Rain](/learn-rxjs/recipes/matrix-digital-rain)
* [Memory Game](/learn-rxjs/recipes/memory-game)
* [Mine Sweeper Game](/learn-rxjs/recipes/mine-sweeper-game)
* [Platform Jumper Game](/learn-rxjs/recipes/platform-jumper-game)
* [Progress Bar](/learn-rxjs/recipes/progressbar)
* [Save Indicator](/learn-rxjs/recipes/save-indicator)
* [Smart Counter](/learn-rxjs/recipes/smartcounter)
* [Stop Watch](/learn-rxjs/recipes/stop-watch)
* [Space Invaders Game](/learn-rxjs/recipes/space-invaders-game)
* [Swipe To Refresh](/learn-rxjs/recipes/swipe-to-refresh)
* [Tank Battle Game](/learn-rxjs/recipes/tank-battle-game)
* [Tetris Game](/learn-rxjs/recipes/tetris-game)
* [Type Ahead](/learn-rxjs/recipes/type-ahead)
* [Uncover Image Game](/learn-rxjs/recipes/uncover-image-game)

## Introductory Resources

New to RxJS and reactive programming? In addition to the content found on this site, these excellent resources will help jump start your learning experience!

#### Conferences

* [RxJS Live](https://www.youtube.com/@rxjslive2237) - RxJS specific conference

#### Reading

* [RxJS Introduction](https://rxjs-dev.firebaseapp.com/guide/overview) - Official Docs
* [The Introduction to Reactive Programming You've Been Missing](https://gist.github.com/staltz/868e7e9bc2a7b8c1f754) - André Staltz
* [RxJS: Observables, Observers and Operators Introduction](https://ultimatecourses.com/blog/rxjs-observables-observers-operators) - Todd Motto

#### Videos

* [Ultimate RxJS](https://ultimatecourses.com/courses/rxjs?ref=4) 💵 - Brian Troncone
* [Asynchronous Programming: The End of The Loop](https://egghead.io/courses/asynchronous-programming-the-end-of-the-loop) - Jafar Husain
* [What is RxJS?](https://egghead.io/lessons/rxjs-what-is-rxjs) - Ben Lesh
* [Creating Observable from Scratch](https://egghead.io/lessons/rxjs-creating-observable-from-scratch) - Ben Lesh
* [Introduction to RxJS Marble Testing](https://egghead.io/lessons/rxjs-introduction-to-rxjs-marble-testing) 💵 - Brian Troncone
* [Introduction to Reactive Programming](https://egghead.io/courses/introduction-to-reactive-programming) 💵 - André Staltz
* [Reactive Programming using Observables](https://www.youtube.com/watch?v=HT7JiiqnYYc\&feature=youtu.be) - Jeremy Lund

#### Exercises

* [Functional Programming in JavaScript](http://reactivex.io/learnrx/) - Jafar Husain

#### Tools

* [Rx Marbles - Interactive diagrams of Rx Observables](http://rxmarbles.com/) - André Staltz
* [Rx Visualizer - Animated playground for Rx Observables](https://rxviz.com) - Misha Moroshko
* [Reactive.how - Animated cards to learn Reactive Programming](http://reactive.how) - Cédric Soulas
* [Rx Visualization - Visualizes programming with RxJS](https://fingerpich.github.io/rx-visualization/) - Mojtaba Zarei

*Interested in RxJS 4? Check out* [*Denis Stoyanov's*](https://github.com/xgrommx) *excellent* [*eBook*](https://xgrommx.github.io/rx-book/)*!*

## Translations

* [简体中文](https://rxjs-cn.github.io/learn-rxjs-operators)

### A Note On References

All references included in this GitBook are resources, both free and paid, that helped me tremendously while learning RxJS. If you come across an article or video that you think should be included, please use the *edit this page* link in the top menu and submit a pull request. Your feedback is appreciated!

***

Thank you to [Gitbook](https://www.gitbook.com/) for sponsoring this documentation!


# Operators

A complete list of RxJS operators with clear explanations, relevant resources, and executable examples.

[*Prefer a complete list in alphabetical order?*](/learn-rxjs/operators/complete)

### Contents (By Operator Type)

* [Combination](/learn-rxjs/operators/combination)
  * [combineLatestAll](/learn-rxjs/operators/combination/combineall)
  * [combineLatest](/learn-rxjs/operators/combination/combinelatest) ⭐
  * [concat](/learn-rxjs/operators/combination/concat) ⭐
  * [concatAll](/learn-rxjs/operators/combination/concatall)
  * [endWith](/learn-rxjs/operators/combination/endwith)
  * [forkJoin](/learn-rxjs/operators/combination/forkjoin)
  * [merge](/learn-rxjs/operators/combination/merge) ⭐
  * [mergeAll](/learn-rxjs/operators/combination/mergeall)
  * [pairwise](/learn-rxjs/operators/combination/pairwise)
  * [race](/learn-rxjs/operators/combination/race)
  * [startWith](/learn-rxjs/operators/combination/startwith) ⭐
  * [withLatestFrom](/learn-rxjs/operators/combination/withlatestfrom) ⭐
  * [zip](/learn-rxjs/operators/combination/zip)
* [Conditional](/learn-rxjs/operators/conditional)
  * [defaultIfEmpty](/learn-rxjs/operators/conditional/defaultifempty)
  * [every](/learn-rxjs/operators/conditional/every)
  * [iif](/learn-rxjs/operators/conditional/iif)
  * [sequenceequal](/learn-rxjs/operators/conditional/sequenceequal)
* [Creation](/learn-rxjs/operators/creation)
  * [ajax](/learn-rxjs/operators/creation/ajax) ⭐
  * [create](/learn-rxjs/operators/creation/create)
  * [defer](/learn-rxjs/operators/creation/defer)
  * [empty](/learn-rxjs/operators/creation/empty)
  * [from](/learn-rxjs/operators/creation/from) ⭐
  * [fromEvent](/learn-rxjs/operators/creation/fromevent)
  * [generate](/learn-rxjs/operators/creation/generate)
  * [interval](/learn-rxjs/operators/creation/interval)
  * [of](/learn-rxjs/operators/creation/of) ⭐
  * [range](/learn-rxjs/operators/creation/range)
  * [throwError](/learn-rxjs/operators/creation/throw)
  * [timer](/learn-rxjs/operators/creation/timer)
* [Error Handling](/learn-rxjs/operators/error_handling)
  * [catch / catchError](/learn-rxjs/operators/error_handling/catch) ⭐
  * [retry](/learn-rxjs/operators/error_handling/retry)
  * [retryWhen](/learn-rxjs/operators/error_handling/retrywhen)
* [Filtering](/learn-rxjs/operators/filtering)
  * [audit](/learn-rxjs/operators/filtering/audit)
  * [auditTime](/learn-rxjs/operators/filtering/audittime)
  * [debounce](/learn-rxjs/operators/filtering/debounce)
  * [debounceTime](/learn-rxjs/operators/filtering/debouncetime) ⭐
  * [distinct](/learn-rxjs/operators/filtering/distinct)
  * [distinctUntilChanged](/learn-rxjs/operators/filtering/distinctuntilchanged) ⭐
  * [distinctUntilKeyChanged](/learn-rxjs/operators/filtering/distinctuntilkeychanged)
  * [filter](/learn-rxjs/operators/filtering/filter) ⭐
  * [find](/learn-rxjs/operators/filtering/find)
  * [first](/learn-rxjs/operators/filtering/first)
  * [ignoreElements](/learn-rxjs/operators/filtering/ignoreelements)
  * [last](/learn-rxjs/operators/filtering/last)
  * [sample](/learn-rxjs/operators/filtering/sample)
  * [single](/learn-rxjs/operators/filtering/single)
  * [skip](/learn-rxjs/operators/filtering/skip)
  * [skipUntil](/learn-rxjs/operators/filtering/skipuntil)
  * [skipWhile](/learn-rxjs/operators/filtering/skipwhile)
  * [take](/learn-rxjs/operators/filtering/take) ⭐
  * [takeLast](/learn-rxjs/operators/filtering/takelast)
  * [takeUntil](/learn-rxjs/operators/filtering/takeuntil) ⭐
  * [takeWhile](/learn-rxjs/operators/filtering/takewhile)
  * [throttle](/learn-rxjs/operators/filtering/throttle)
  * [throttleTime](/learn-rxjs/operators/filtering/throttletime)
* [Multicasting](/learn-rxjs/operators/multicasting)
  * [multicast](/learn-rxjs/operators/multicasting/multicast)
  * [publish](/learn-rxjs/operators/multicasting/publish)
  * [share](/learn-rxjs/operators/multicasting/share) ⭐
  * [shareReplay](/learn-rxjs/operators/multicasting/sharereplay) ⭐
* [Transformation](/learn-rxjs/operators/transformation)
  * [buffer](/learn-rxjs/operators/transformation/buffer)
  * [bufferCount](/learn-rxjs/operators/transformation/buffercount)
  * [bufferTime](/learn-rxjs/operators/transformation/buffertime) ⭐
  * [bufferToggle](/learn-rxjs/operators/transformation/buffertoggle)
  * [bufferWhen](/learn-rxjs/operators/transformation/bufferwhen)
  * [concatMap](/learn-rxjs/operators/transformation/concatmap) ⭐
  * [concatMapTo](/learn-rxjs/operators/transformation/concatmapto)
  * [expand](/learn-rxjs/operators/transformation/expand)
  * [exhaustMap](/learn-rxjs/operators/transformation/exhaustmap)
  * [groupBy](/learn-rxjs/operators/transformation/groupby)
  * [map](/learn-rxjs/operators/transformation/map) ⭐
  * [mapTo](/learn-rxjs/operators/transformation/mapto)
  * [mergeMap / flatMap](/learn-rxjs/operators/transformation/mergemap) ⭐
  * [mergeScan](/learn-rxjs/operators/transformation/mergescan)
  * [partition](/learn-rxjs/operators/transformation/partition)
  * [pluck](/learn-rxjs/operators/transformation/pluck)
  * [reduce](/learn-rxjs/operators/transformation/reduce)
  * [scan](/learn-rxjs/operators/transformation/scan) ⭐
  * [switchMap](/learn-rxjs/operators/transformation/switchmap) ⭐
  * [switchMapTo](/learn-rxjs/operators/transformation/switchmapto)
  * [toArray](/learn-rxjs/operators/transformation/toarray)
  * [window](/learn-rxjs/operators/transformation/window)
  * [windowCount](/learn-rxjs/operators/transformation/windowcount)
  * [windowTime](/learn-rxjs/operators/transformation/windowtime)
  * [windowToggle](/learn-rxjs/operators/transformation/windowtoggle)
  * [windowWhen](/learn-rxjs/operators/transformation/windowwhen)
* [Utility](/learn-rxjs/operators/utility)
  * [tap / do](/learn-rxjs/operators/utility/do) ⭐
  * [delay](/learn-rxjs/operators/utility/delay)
  * [delayWhen](/learn-rxjs/operators/utility/delaywhen)
  * [dematerialize](/learn-rxjs/operators/utility/dematerialize)
  * [finalize / finally](/learn-rxjs/operators/utility/finalize)
  * [let](/learn-rxjs/operators/utility/let)
  * [repeat](/learn-rxjs/operators/utility/repeat)
  * [repeatWhen](https://github.com/btroncone/learn-rxjs/blob/master/operators/utility/repeatwhen.md)
  * [timeInterval](/learn-rxjs/operators/utility/timeinterval)
  * [timeout](/learn-rxjs/operators/utility/timeout)
  * [timeoutWith](/learn-rxjs/operators/utility/timeoutwith)
  * [toPromise](/learn-rxjs/operators/utility/topromise)

⭐ - *commonly used*

### Additional Resources

* [What Are Operators?](http://reactivex.io/rxjs/manual/overview.html#operators) 📰 - Official Docs
* [What Operators Are](https://egghead.io/lessons/rxjs-what-rxjs-operators-are) 🎥 💵 - André Staltz


# Combination

The combination operators allow the joining of information from multiple observables. Order, time, and structure of emitted values is the primary variation among these operators.

## Contents

* [combineLatestAll](/learn-rxjs/operators/combination/combineall)
* [combineLatest](/learn-rxjs/operators/combination/combinelatest) ⭐
* [concat](/learn-rxjs/operators/combination/concat) ⭐
* [concatAll](/learn-rxjs/operators/combination/concatall)
* [endWith](/learn-rxjs/operators/combination/endwith)
* [forkJoin](/learn-rxjs/operators/combination/forkjoin)
* [merge](/learn-rxjs/operators/combination/merge) ⭐
* [mergeAll](/learn-rxjs/operators/combination/mergeall)
* [pairwise](/learn-rxjs/operators/combination/pairwise)
* [race](/learn-rxjs/operators/combination/race)
* [startWith](/learn-rxjs/operators/combination/startwith) ⭐
* [withLatestFrom](/learn-rxjs/operators/combination/withlatestfrom) ⭐
* [zip](/learn-rxjs/operators/combination/zip)

⭐ - *commonly used*


# combineLatestAll

## Signature

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

Flattens a higher-order observable by applying [combineLatest](/learn-rxjs/operators/combination/combinelatest) when the outer observable completes.

***

💡 `combineLatestAll` is best used when you're working with a **higher-order observable** (an observable that emits other observables) and need to track the most recent values from each inner observable 💡 Unlike [`mergeAll`](https://github.com/btroncone/learn-rxjs/blob/master/operators/combination/mergeall/README.md) which emits values as soon as any inner observable emits, `combineLatestAll` waits for **all inner observables to emit at least once** before producing output 💡 If you need only the final values when all observables complete (not ongoing updates), consider [`forkJoin`](https://github.com/btroncone/learn-rxjs/blob/master/operators/combination/forkjoin/README.md) instead

***

## Why use combineLatestAll?

Think of `combineLatestAll` as organizing a panel discussion where speakers join at different times. You can't start the broadcast until everyone has joined, but after that, whenever anyone speaks again, you broadcast the most recent statement from each panelist. That's exactly how `combineLatestAll` manages your observable streams.

This operator shines when you're dealing with **dynamic collections of observables**, or situations where you don't know upfront how many observables you'll have, but they're being emitted by a source stream. A practical example is when you [map a stream of events to interval observables](#example-1-mapping-to-inner-interval-observable) and want to monitor the latest value from each one simultaneously. It's particularly useful for scenarios like tracking multiple user sessions, monitoring real-time dashboard widgets that get added dynamically, or combining results from a variable number of API calls.

Keep in mind that `combineLatestAll` won't produce any values until two conditions are met: the outer observable must **complete** (signaling that no more inner observables will be emitted), and every inner observable must have **emitted at least once**. This "wait for everyone" behavior can be a gotcha if one of your inner observables never emits or never completes—your stream will remain silent.

In essence, `combineLatestAll` transforms a stream of streams into a single stream that keeps you updated with the latest snapshot from each member of your dynamic collection.

***

## Examples

### Example 1: Mapping to inner interval observable

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

```typescript
import { interval } from 'rxjs';
import { take, map, combineLatestAll } from 'rxjs/operators';

// Emit every 1s, take 2
const source$ = interval(1000).pipe(take(2));

// Map each emitted value from source to interval observable that takes 5 values
const example$ = source$.pipe(
  map(val =>
    interval(1000).pipe(
      map(i => `Result (${val}): ${i}`),
      take(5)
    )
  )
);

/*
  2 values from source will map to 2 (inner) interval observables that emit every 1s.
  combineLatestAll uses combineLatest strategy, emitting the last value from each
  whenever either observable emits a value
*/
example$
  .pipe(combineLatestAll())
  /*
    output:
    ["Result (0): 0", "Result (1): 0"]
    ["Result (0): 1", "Result (1): 0"]
    ["Result (0): 1", "Result (1): 1"]
    ["Result (0): 2", "Result (1): 1"]
    ["Result (0): 2", "Result (1): 2"]
    ["Result (0): 3", "Result (1): 2"]
    ["Result (0): 3", "Result (1): 3"]
    ["Result (0): 4", "Result (1): 3"]
    ["Result (0): 4", "Result (1): 4"]
  */
  .subscribe(console.log);
```

***

## Related Recipes

* [Smart Counter](/learn-rxjs/recipes/smartcounter)
* [HTTP Polling](/learn-rxjs/recipes/http-polling)

***

## Additional Resources

* [combineLatestAll](https://rxjs.dev/api/index/function/combineLatestAll) 📰 - Official docs
* [combineLatest](https://github.com/btroncone/learn-rxjs/blob/master/operators/combination/combinelatest/README.md) - Learn about the underlying combination strategy

***

📁 **Source Code**: <https://github.com/ReactiveX/rxjs/blob/master/packages/rxjs/src/internal/operators/combineLatestAll.ts>


# combineLatest

#### signature: `combineLatest(observables: ...Observable, project: function): Observable`

## When any observable emits a value, emit the last emitted value from each.

***

💡 [combineLatestAll](/learn-rxjs/operators/combination/combineall) can be used to apply combineLatest to emitted observables when a source completes!

***

### Why use `combineLatest`?

This operator is best used when you have multiple, long-lived observables that rely on each other for some calculation or determination. Basic examples of this can be seen in [example three](#example-3-combining-events-from-2-buttons), where events from multiple buttons are being combined to produce a count of each and an overall total, or a [calculation of BMI](http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#instance-method-combineLatest) from the RxJS documentation.

Be aware that **`combineLatest` will not emit an initial value until each observable emits at least one value**. This is the same behavior as [`withLatestFrom`](/learn-rxjs/operators/combination/withlatestfrom) and can be a *gotcha* as there will be no output and no error but one (or more) of your inner observables is likely not functioning as intended, or a subscription is late.

Lastly, if you are working with observables that only emit one value, or you only require the last value of each before completion, [`forkJoin`](/learn-rxjs/operators/combination/forkjoin) is likely a better option.

### Examples

**Example 1: Combining observables emitting at 3 intervals**

( [StackBlitz](https://stackblitz.com/edit/typescript-vadvm2?file=index.ts\&devtoolsheight=100) )

```js
// RxJS v6+
import { timer, combineLatest } from 'rxjs';

// timerOne emits first value at 1s, then once every 4s
const timerOne$ = timer(1000, 4000);
// timerTwo emits first value at 2s, then once every 4s
const timerTwo$ = timer(2000, 4000);
// timerThree emits first value at 3s, then once every 4s
const timerThree$ = timer(3000, 4000);

// when one timer emits, emit the latest values from each timer as an array
combineLatest(timerOne$, timerTwo$, timerThree$).subscribe(
  ([timerValOne, timerValTwo, timerValThree]) => {
    /*
  	Example:
    timerThree first tick: 'Timer One Latest: 0, Timer Two Latest: 0, Timer Three Latest: 0
    timerOne second tick: 'Timer One Latest: 1, Timer Two Latest: 0, Timer Three Latest: 0
    timerTwo second tick: 'Timer One Latest: 1, Timer Two Latest: 1, Timer Three Latest: 0
  */
    console.log(
      `Timer One Latest: ${timerValOne},
     Timer Two Latest: ${timerValTwo},
     Timer Three Latest: ${timerValThree}`
    );
  }
);
```

**Example 2: combineLatest with projection function**

( [StackBlitz](https://stackblitz.com/edit/typescript-prtbvd?file=index.ts\&devtoolsheight=100) )

```js
// RxJS v6+
import { timer, combineLatest } from 'rxjs';

const timerOne$ = timer(1000, 4000);
const timerTwo$ = timer(2000, 4000);
const timerThree$ = timer(3000, 4000);

combineLatest(
  timerOne$,
  timerTwo$,
  timerThree$,
  // combineLatest also takes an optional projection function
  (one, two, three) => {
    return `Timer One (Proj) Latest: ${one}, 
              Timer Two (Proj) Latest: ${two}, 
              Timer Three (Proj) Latest: ${three}`;
  }
).subscribe(console.log);
```

**Example 3: Combining events from 2 buttons**

( [StackBlitz](https://stackblitz.com/edit/typescript-ihcxud?file=index.ts\&devtoolsheight=50) )

```js
// RxJS v6+
import { fromEvent, combineLatest } from 'rxjs';
import { mapTo, startWith, scan, tap, map } from 'rxjs/operators';

// elem refs
const redTotal = document.getElementById('red-total');
const blackTotal = document.getElementById('black-total');
const total = document.getElementById('total');

const addOneClick$ = id =>
  fromEvent(document.getElementById(id), 'click').pipe(
    // map every click to 1
    mapTo(1),
    // keep a running total
    scan((acc, curr) => acc + curr, 0),
    startWith(0)
  );

combineLatest(addOneClick$('red'), addOneClick$('black')).subscribe(
  ([red, black]: any) => {
    redTotal.innerHTML = red;
    blackTotal.innerHTML = black;
    total.innerHTML = red + black;
  }
);
```

**HTML**

```html
<div>
  <button id="red">Red</button>
  <button id="black">Black</button>
</div>
<div>Red: <span id="red-total"></span></div>
<div>Black: <span id="black-total"></span></div>
<div>Total: <span id="total"></span></div>
```

### Related Recipes

* [Alphabet Invasion Game](/learn-rxjs/recipes/alphabet-invasion-game)
* [Breakout Game](/learn-rxjs/recipes/breakout-game)
* [Car Racing Game](/learn-rxjs/recipes/car-racing-game)
* [Flappy Bird Game](/learn-rxjs/recipes/flappy-bird-game)
* [Platform Jumper Game](/learn-rxjs/recipes/platform-jumper-game)
* [Tank Battle Game](/learn-rxjs/recipes/tank-battle-game)
* [Tetris Game](/learn-rxjs/recipes/tetris-game)

### Additional Resources

* [combineLatest](https://rxjs.dev/api/index/function/combineLatest) 📰 - Official docs

***

> 📁 Source Code: <https://github.com/ReactiveX/rxjs/blob/master/packages/rxjs/src/internal/operators/combineLatest.ts>


# concat

#### signature: `concat(observables: ...*): Observable`

## Subscribe to observables in order as previous completes

***

💡 You can think of concat like a line at a ATM, the next transaction (subscription) cannot start until the previous completes!

💡 If throughput, not order, is a primary concern, try [merge](/learn-rxjs/operators/combination/merge) instead!

***

### Why use `concat`?

The concat operator is best used when you need to combine multiple observables, but you want their emissions to be in a specific order, one after the other. It's like putting together a puzzle where the pieces must come together sequentially to create the full picture. An example of this can be seen in a real-world scenario, like downloading and displaying several images in the correct order, where you don't want the next image to load until the current one is fully loaded.

Keep in mind that concat will only start emitting values from the next observable once the previous one has completed. This means that if one of your observables never completes, the subsequent observables will never emit any values. This behavior can be a *gotcha*, as there will be no output and no error, but one (or more) of your inner observables might not be functioning as intended, or a subscription is not being set up correctly.

In contrast, if you need to combine observables that emit values concurrently, or you require the latest values from multiple observables whenever any of them emit a new value, [combineLatest](/learn-rxjs/operators/combination/combinelatest) or [withLatestFrom](/learn-rxjs/operators/combination/withlatestfrom) might be more suitable options.

### Examples

**Example 1: Basic concat usage with three observables**

( [StackBlitz](https://stackblitz.com/edit/typescript-ks8chl?file=index.ts\&devtoolsheight=100) )

```js
// RxJS v6+
import { of, concat } from 'rxjs';

concat(
  of(1, 2, 3),
  // subscribed after first completes
  of(4, 5, 6),
  // subscribed after second completes
  of(7, 8, 9)
)
  // log: 1, 2, 3, 4, 5, 6, 7, 8, 9
  .subscribe(console.log);
```

**Example 2: Display message using concat with delayed observables**

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

![Example 2](https://drive.google.com/uc?export=view\&id=1fKsYUKXkSWEDLdii-5rmOAgqy6sUGNjl)

```js
// RxJS v6+
import { concat, empty } from 'rxjs';
import { delay, startWith } from 'rxjs/operators';

// elems
const userMessage = document.getElementById('message');
// helper
const delayedMessage = (message, delayedTime = 1000) => {
  return empty().pipe(startWith(message), delay(delayedTime));
};

concat(
  delayedMessage('Get Ready!'),
  delayedMessage(3),
  delayedMessage(2),
  delayedMessage(1),
  delayedMessage('Go!'),
  delayedMessage('', 2000)
).subscribe((message: any) => (userMessage.innerHTML = message));
```

**Example 3: (Warning!) concat with source that does not complete**

( [StackBlitz](https://stackblitz.com/edit/typescript-njc2jw?file=index.ts\&devtoolsheight=100) )

```js
// RxJS v6+
import { interval, of, concat } from 'rxjs';

// when source never completes, any subsequent observables never run
concat(interval(1000), of('This', 'Never', 'Runs'))
  // log: 1,2,3,4.....
  .subscribe(console.log);
```

### Related Recipes

* [Battleship Game](/learn-rxjs/recipes/battleship-game)
* [Save Indicator](/learn-rxjs/recipes/save-indicator)

### Additional Resources

* [concat](https://rxjs.dev/api/index/function/concat) 📰 - Official docs
* [Combination operator: concat, startWith](https://egghead.io/lessons/rxjs-combination-operators-concat-startwith?course=rxjs-beyond-the-basics-operators-in-depth) 🎥 💵 - André Staltz

***

> 📁 Source Code: <https://github.com/ReactiveX/rxjs/blob/master/packages/rxjs/src/internal/operators/concat.ts>


# concatAll

#### signature: `concatAll(): Observable`

## Collect observables and subscribe to next when previous completes.

***

⚠ Be wary of [backpressure](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/gettingstarted/backpressure.md) when the source emits at a faster pace than inner observables complete!

💡 In many cases you can use [concatMap](/learn-rxjs/operators/transformation/concatmap) as a single operator instead!

***

### Why use `concatAll`?

This operator is best used when you have multiple observables that need to be processed sequentially, ensuring that each observable completes before moving on to the next. Real-world examples of this can be seen in scenarios such as uploading multiple files to a server one-by-one, or displaying a sequence of animations in order.

Bear in mind that `concatAll` will only start processing the next observable when the current one completes. This is an important consideration if you have observables that emit values indefinitely or take a long time to complete, as it may cause a delay in processing subsequent observables.

Additionally, if you're working with observables that can emit values concurrently and don't need to wait for one to complete before processing another, [mergeAll](/learn-rxjs/operators/combination/mergeall) might be a more suitable choice. Similarly, if you only need to combine the values of multiple observables at the point when they all complete, [forkJoin](/learn-rxjs/operators/combination/forkjoin) could be a better option.

### Examples

( [example tests](https://github.com/btroncone/learn-rxjs/blob/master/operators/specs/combination/concatall-spec.ts) )

**Example 1: concatAll with observable**

( [StackBlitz](https://stackblitz.com/edit/typescript-zwtpc7?file=index.ts\&devtoolsheight=100) | [jsBin](http://jsbin.com/nakinenuva/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/8dfuf2y6/) )

```js
// RxJS v6+
import { map, concatAll } from 'rxjs/operators';
import { of, interval } from 'rxjs';

//emit a value every 2 seconds
const source = interval(2000);
const example = source.pipe(
  //for demonstration, add 10 to and return as observable
  map(val => of(val + 10)),
  //merge values from inner observable
  concatAll()
);
//output: 'Example with Basic Observable 10', 'Example with Basic Observable 11'...
const subscribe = example.subscribe(val =>
  console.log('Example with Basic Observable:', val)
);
```

**Example 2: concatAll with promise**

( [StackBlitz](https://stackblitz.com/edit/typescript-3w4px3?file=index.ts\&devtoolsheight=100) | [jsBin](http://jsbin.com/bekegeyopu/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/w7kp7qLs/) )

```js
// RxJS v6+
import { map, concatAll } from 'rxjs/operators';
import { interval } from 'rxjs';

//create and resolve basic promise
const samplePromise = val => new Promise(resolve => resolve(val));
//emit a value every 2 seconds
const source = interval(2000);

const example = source.pipe(
  map(val => samplePromise(val)),
  //merge values from resolved promise
  concatAll()
);
//output: 'Example with Promise 0', 'Example with Promise 1'...
const subscribe = example.subscribe(val =>
  console.log('Example with Promise:', val)
);
```

**Example 3: Delay while inner observables complete**

( [StackBlitz](https://stackblitz.com/edit/typescript-ft3rbf?file=index.ts\&devtoolsheight=100) | [jsBin](http://jsbin.com/pojolatile/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/8230ucbg/) )

```js
// RxJS v6+
import { take, concatAll } from 'rxjs/operators';
import { interval, of } from 'rxjs';

const obs1 = interval(1000).pipe(take(5));
const obs2 = interval(500).pipe(take(2));
const obs3 = interval(2000).pipe(take(1));
//emit three observables
const source = of(obs1, obs2, obs3);
//subscribe to each inner observable in order when previous completes
const example = source.pipe(concatAll());
/*
  output: 0,1,2,3,4,0,1,0
  How it works...
  Subscribes to each inner observable and emit values, when complete subscribe to next
  obs1: 0,1,2,3,4 (complete)
  obs2: 0,1 (complete)
  obs3: 0 (complete)
*/

const subscribe = example.subscribe(val => console.log(val));
```

### Related Recipes

* [Progress Bar](/learn-rxjs/recipes/progressbar)

### Additional Resources

* [concatAll](https://rxjs.dev/api/operators/concatAll) 📰 - Official docs
* [Flatten a higher order observable with concatAll in RxJS](https://egghead.io/lessons/rxjs-flatten-a-higher-order-observable-with-concatall-in-rxjs?course=use-higher-order-observables-in-rxjs-effectively) 🎥 💵 - André Staltz

***

> 📁 Source Code: <https://github.com/ReactiveX/rxjs/blob/master/packages/rxjs/src/internal/operators/concatAll.ts>


# endWith

#### signature: `endWith(an: Values): Observable`

## Emit given value(s) on completion.

***

💡 If you want to start with a value instead, check out [`startWith`](/learn-rxjs/operators/combination/startwith)!

💡 If you want to perform an action on completion, but do not want to emit a value, check out [`finalize`](/learn-rxjs/operators/utility/finalize)!

***

### Why use `endWith`?

The `endWith` operator is especially handy when you want to ensure that a specific value is emitted after the source observable completes. Think of it as the closing credits of a movie, signaling that the story has reached its conclusion. Real-world examples of endWith can be found in scenarios where you want to append a specific message or status update after a series of events, such as a file download that ends with a "Download Complete" notification or a countdown timer that finishes with a "Time's Up!" alert.

Keep in mind that endWith only emits the specified value when the source observable completes. This means that if your source observable does not complete, the value provided to `endWith` will not be emitted. To avoid surprises, make sure to check that your source observable is designed to complete at some point.

In cases where you want to prepend a value at the beginning of an observable sequence instead of appending it at the end, consider using the [startWith](/learn-rxjs/operators/combination/startwith) operator.

### Examples

**Example 1: Basic `endWith` example**

( [StackBlitz](https://stackblitz.com/edit/typescript-gexe9u?file=index.ts\&devtoolsheight=100) )

```js
// RxJS v6+
import { endWith } from 'rxjs/operators';
import { of } from 'rxjs';

const source$ = of('Hello', 'Friend', 'Goodbye');

source$
  // emit on completion
  .pipe(endWith('Friend'))
  // 'Hello', 'Friend', 'Goodbye', 'Friend'
  .subscribe(console.log(val));
```

**Example 2: endWith multiple values**

( [StackBlitz](https://stackblitz.com/edit/typescript-dyed7x?file=index.ts\&devtoolsheight=100) )

```js
// RxJS v6+
import { endWith } from 'rxjs/operators';
import { of } from 'rxjs';

const source$ = of('Hello', 'Friend');

source$
  // emit on completion
  .pipe(endWith('Goodbye', 'Friend'))
  // 'Hello', 'Friend', 'Goodbye', 'Friend'
  .subscribe(console.log(val));
```

**Example 3: Comparison to** [**`finalize`**](/learn-rxjs/operators/utility/finalize)

( [StackBlitz](https://stackblitz.com/edit/typescript-lkk1pj?file=index.ts\&devtoolsheight=100) )

```js
// RxJS v6+
import { endWith, finalize } from 'rxjs/operators';
import { of } from 'rxjs';

const source$ = of('Hello', 'Friend');

source$
  // emit on completion
  .pipe(
    endWith('Goodbye', 'Friend'),
    // this function is invoked when unsubscribe methods are called
    finalize(() => console.log('Finally'))
  )
  // 'Hello', 'Friend', 'Goodbye', 'Friend'
  .subscribe(val => console.log(val));
// 'Finally'
```

### Additional Resources

* [endWith](https://rxjs.dev/api/operators/endWith) 📰 - Official docs

***

> 📁 Source Code: <https://github.com/ReactiveX/rxjs/blob/master/packages/rxjs/src/internal/operators/endWith.ts>


# forkJoin

#### signature: `forkJoin(...args, selector : function): Observable`

## When all observables complete, emit the last emitted value from each.

***

💡 If you want corresponding emissions from multiple observables as they occur, try [zip](/learn-rxjs/operators/combination/zip)!

⚠ If an inner observable does not complete `forkJoin` will never emit a value!

***

### Why use `forkJoin`?

This operator is best used when you have a group of observables and only care about the final emitted value of each. One common use case for this is if you wish to issue multiple requests on page load (or some other event) and only want to take action when a response has been received for all. In this way it is similar to how you might use [`Promise.all`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all).

Be aware that if any of the inner observables supplied to `forkJoin` error you will lose the value of any other observables that would or have already completed if you do not [`catch`](/learn-rxjs/operators/error_handling/catch) the [error correctly on the inner observable](#example-4-getting-successful-results-when-one-innner-observable-errors). If you are only concerned with all inner observables completing successfully you can [catch the error on the outside](#example-3-handling-errors-on-outside).

It's also worth noting that if you have an observable that emits more than one item, and you are concerned with the previous emissions `forkJoin` is not the correct choice. In these cases you may be better off with an operator like [combineLatest](/learn-rxjs/operators/combination/combinelatest) or [zip](/learn-rxjs/operators/combination/zip).

### Examples

**Example 1: Using a dictionary of sources to make AJAX request**

( [StackBlitz](https://stackblitz.com/edit/typescript-u5pzuf?file=index.ts\&devtoolsheight=100) )

```js
// RxJS v6.5+
import { ajax } from 'rxjs/ajax';
import { forkJoin } from 'rxjs';

/*
  when all observables complete, provide the last
  emitted value from each as dictionary
*/
forkJoin(
  // as of RxJS 6.5+ we can use a dictionary of sources
  {
    google: ajax.getJSON('https://api.github.com/users/google'),
    microsoft: ajax.getJSON('https://api.github.com/users/microsoft'),
    users: ajax.getJSON('https://api.github.com/users')
  }
)
  // { google: object, microsoft: object, users: array }
  .subscribe(console.log);
```

**Example 2: Observables completing after different durations**

( [StackBlitz](https://stackblitz.com/edit/typescript-c3f62b?file=index.ts\&devtoolsheight=100) )

```js
// RxJS v6+
import { interval, forkJoin, of } from 'rxjs';
import { delay, take } from 'rxjs/operators';

const myPromise = val =>
  new Promise(resolve =>
    setTimeout(() => resolve(`Promise Resolved: ${val}`), 5000)
  );

/*
  when all observables complete, give the last
  emitted value from each as an array
*/
const example = forkJoin({
  //emit 'Hello' immediately
  sourceOne: of('Hello'),
  //emit 'World' after 1 second
  sourceTwo: of('World').pipe(delay(1000)),
  //emit 0 after 1 second
  sourceThree: interval(1000).pipe(take(1)),
  //emit 0...1 in 1 second interval
  sourceFour: interval(1000).pipe(take(2)),
  //promise that resolves to 'Promise Resolved' after 5 seconds
  sourceFive: myPromise('RESULT')
});
/*
 * Output:
 * { 
 *   sourceOne: "Hello", 
 *   sourceTwo: "World", 
 *   sourceThree: 0,
 *   sourceFour: 1,
 *   sourceFive: "Promise Resolved: RESULT"
 * }
 */
const subscribe = example.subscribe(val => console.log(val));
```

**Example 3: Making a variable number of requests (uses deprecated API)**

( [StackBlitz](https://stackblitz.com/edit/typescript-3mbbjw?file=index.ts\&devtoolsheight=100) )

```js
// RxJS v6+
import { mergeMap } from 'rxjs/operators';
import { forkJoin, of } from 'rxjs';

const myPromise = val =>
  new Promise(resolve =>
    setTimeout(() => resolve(`Promise Resolved: ${val}`), 5000)
  );

const source = of([1, 2, 3, 4, 5]);
//emit array of all 5 results
const example = source.pipe(mergeMap(q => forkJoin(...q.map(myPromise))));
/*
  output:
  [
   "Promise Resolved: 1",
   "Promise Resolved: 2",
   "Promise Resolved: 3",
   "Promise Resolved: 4",
   "Promise Resolved: 5"
  ]
*/
const subscribe = example.subscribe(val => console.log(val));
```

**Example 4: Handling errors on outside**

( [StackBlitz](https://stackblitz.com/edit/typescript-petcwk?file=index.ts\&devtoolsheight=100) )

```js
// RxJS v6+
import { delay, catchError } from 'rxjs/operators';
import { forkJoin, of, throwError } from 'rxjs';

/*
  If any inner observables error, the error result
  will be emitted by catchError.
*/
const example = forkJoin({
  // emit 'Hello' immediately
  sourceOne: of('Hello'),
  // emit 'World' after 1 second
  sourceTwo: of('World').pipe(delay(1000)),
  // throw error
  sourceThree: throwError('This will error')
}).pipe(catchError(error => of(error)));

// output: 'This will Error'
const subscribe = example.subscribe(val => console.log(val));
```

**Example 5: Getting successful results when one inner observable errors**

( [StackBlitz](https://stackblitz.com/edit/typescript-7qcyvz?file=index.ts\&devtoolsheight=100) )

```js
// RxJS v6+
import { delay, catchError } from 'rxjs/operators';
import { forkJoin, of, throwError } from 'rxjs';

/*
  Emit values from successfully completed
  inner observables.
*/
const example = forkJoin({
  // emit 'Hello' immediately
  sourceOne: of('Hello'),
  // emit 'World' after 1 second
  sourceTwo: of('World').pipe(delay(1000)),
  // throw error
  sourceThree: throwError('This will error').pipe(catchError(error => of(error)))
});

/*
 * Output:
 * {
 *   sourceOne: "Hello",
 *   sourceTwo: "World",
 *   sourceThree: "This will error"
 * }
 */
const subscribe = example.subscribe(val => console.log(val));
```

**Example 6: forkJoin in Angular**

```js
@Injectable()
export class MyService {
  makeRequest(value: string, delayDuration: number) {
    // simulate http request
    return of(`Complete: ${value}`).pipe(
      delay(delayDuration)
    );
  }
}

@Component({
  selector: 'my-app',
  template: `
    <div>
      <h2>forkJoin Example</h2>
      <ul>
        <li> {{propOne}} </li>
        <li> {{propTwo}} </li>
        <li> {{propThree}} </li>
      </ul>
    </div>
  `,
})
export class App {
  public propOne: string;
  public propTwo: string;
  public propThree: string;
  constructor(private _myService: MyService) {}

  ngOnInit() {
    // simulate 3 requests with different delays
    forkJoin({
      requestOne: this._myService.makeRequest('Request One', 2000),
      requestTwo: this._myService.makeRequest('Request Two', 1000),
      requestThree: this._myService.makeRequest('Request Three', 3000)
    })
    .subscribe(({requestOne, requestTwo, requestThree}) => {
      this.propOne = requestOne;
      this.propTwo = requestTwo;
      this.propThree = requestThree;
    });
  }
}
```

### Additional Resources

* [forkJoin](https://rxjs.dev/api/index/function/forkJoin) 📰 - Official docs

***

> 📁 Source Code: <https://github.com/ReactiveX/rxjs/blob/master/src/internal/observable/forkJoin.ts>


# merge

#### signature: `merge(input: Observable): Observable`

## Turn multiple observables into a single observable.

***

💡 This operator can be used as either a static or instance method!

💡 If order not throughput is a primary concern, try [concat](/learn-rxjs/operators/combination/concat) instead!

***

### Why use merge?

The merge operator is your go-to solution when you have multiple observables that produce values independently and you want to combine their output into a single stream. Think of it as a highway merger, where multiple roads join together to form a single, unified road - the traffic (data) from each road (observable) flows seamlessly together.

A real-world example can be seen in a chat application, where you have separate observables for receiving messages from multiple users. By using `merge`, you can bring all those message streams into a single unified stream for displaying the messages in the chat window.

Keep in mind that `merge` will emit values as soon as any of the observables emit a value. This is different from combineLatest or withLatestFrom, which wait for each observable to emit at least one value before emitting a combined value.

Lastly, if you're dealing with observables that emit values at specific intervals and you need to combine them based on time, consider using the [zip](/learn-rxjs/operators/combination/zip) operator instead.

### Examples

**Example 1: merging multiple observables, static method**

( [StackBlitz](https://stackblitz.com/edit/typescript-ohq6rx?file=index.ts\&devtoolsheight=100) | [jsBin](http://jsbin.com/conufujapi/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/qvq9dscu/) )

```js
// RxJS v6+
import { mapTo } from 'rxjs/operators';
import { interval, merge } from 'rxjs';

//emit every 2.5 seconds
const first = interval(2500);
//emit every 2 seconds
const second = interval(2000);
//emit every 1.5 seconds
const third = interval(1500);
//emit every 1 second
const fourth = interval(1000);

//emit outputs from one observable
const example = merge(
  first.pipe(mapTo('FIRST!')),
  second.pipe(mapTo('SECOND!')),
  third.pipe(mapTo('THIRD')),
  fourth.pipe(mapTo('FOURTH'))
);
//output: "FOURTH", "THIRD", "SECOND!", "FOURTH", "FIRST!", "THIRD", "FOURTH"
const subscribe = example.subscribe(val => console.log(val));
```

**Example 2: merge 2 observables, instance method**

( [StackBlitz](https://stackblitz.com/edit/typescript-bcsl1r?file=index.ts\&devtoolsheight=100) | [jsBin](http://jsbin.com/wuwujokaqu/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/me5ofcr0/) )

```js
// RxJS v6+
import { merge } from 'rxjs/operators';
import { interval } from 'rxjs';

//emit every 2.5 seconds
const first = interval(2500);
//emit every 1 second
const second = interval(1000);
//used as instance method
const example = first.pipe(merge(second));
//output: 0,1,0,2....
const subscribe = example.subscribe(val => console.log(val));
```

### Related Recipes

* [Battleship Game](/learn-rxjs/recipes/battleship-game)
* [Flappy Bird Game](/learn-rxjs/recipes/flappy-bird-game)
* [HTTP Polling](/learn-rxjs/recipes/http-polling)
* [Lockscreen](/learn-rxjs/recipes/lockscreen)
* [Memory Game](/learn-rxjs/recipes/memory-game)
* [Save Indicator](/learn-rxjs/recipes/save-indicator)

### Additional Resources

* [merge](https://rxjs.dev/api/index/function/merge) 📰 - Official docs
* [Handling multiple streams with merge](https://egghead.io/lessons/rxjs-handling-multiple-streams-with-merge?course=step-by-step-async-javascript-with-rxjs) 🎥 💵 - John Linquist
* [Sharing network requests with merge](https://egghead.io/lessons/rxjs-reactive-programming-sharing-network-requests-with-rxjs-merge?course=introduction-to-reactive-programming) 🎥 💵 - André Staltz
* [Combination operator: merge](https://egghead.io/lessons/rxjs-combination-operator-merge?course=rxjs-beyond-the-basics-operators-in-depth) 🎥 💵 - André Staltz

***

> 📁 Source Code: <https://github.com/ReactiveX/rxjs/blob/master/packages/rxjs/src/internal/operators/merge.ts>


# mergeAll

#### signature: `mergeAll(concurrent: number): Observable`

## Collect and subscribe to all observables.

***

💡 In many cases you can use [mergeMap](/learn-rxjs/operators/transformation/mergemap) as a single operator instead!

***

### Why use mergeAll?

This operator is best used when you have multiple, short-lived observables that produce values independently and you want to flatten them into a single output stream. Real-world examples of this can be seen in scenarios like processing multiple requests simultaneously, where each request is an observable and the responses need to be combined into a single stream.

Consider a web page that displays live news updates from different sources. Each source produces updates as separate observables, and you want to merge them all together to show a single feed of news updates. In this case, mergeAll can come to the rescue.

It's essential to note that `mergeAll` will start emitting values as soon as any of the inner observables emit a value. This is different from combineLatest, which waits for each observable to emit at least one value before producing an output.

When deciding between mergeAll and other operators, keep in mind the following:

* If you need to merge multiple observables that rely on each other for calculations or decisions, [`combineLatest`](/learn-rxjs/operators/combination/combinelatest) may be more suitable.
* If you're working with observables that only emit one value or you only require the last value of each before completion, [`forkJoin`](/learn-rxjs/operators/combination/forkjoin) is likely a better choice.
* If you need to merge observables that produce values independently and are short-lived, `mergeAll` is the operator to reach for.

### Examples

( [example tests](https://github.com/btroncone/learn-rxjs/blob/master/operators/specs/combination/mergeall-spec.ts) )

**Example 1: mergeAll with promises**

( [StackBlitz](https://stackblitz.com/edit/typescript-y4ncvc?file=index.ts\&devtoolsheight=100) | [jsBin](http://jsbin.com/worecuhiba/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/0sc4nsxa/) )

```js
// RxJS v6+
import { map, mergeAll } from 'rxjs/operators';
import { of } from 'rxjs';

const myPromise = val =>
  new Promise(resolve => setTimeout(() => resolve(`Result: ${val}`), 2000));
//emit 1,2,3
const source = of(1, 2, 3);

const example = source.pipe(
  //map each value to promise
  map(val => myPromise(val)),
  //emit result from source
  mergeAll()
);

/*
  output:
  "Result: 1"
  "Result: 2"
  "Result: 3"
*/
const subscribe = example.subscribe(val => console.log(val));
```

**Example 2: mergeAll with&#x20;*****concurrent*****&#x20;parameter**

( [StackBlitz](https://stackblitz.com/edit/typescript-xpaqjh?file=index.ts\&devtoolsheight=100) | [jsFiddle](https://jsfiddle.net/zra3zxhs/) )

```js
// RxJS v6+
import { take, map, delay, mergeAll } from 'rxjs/operators';
import { interval } from 'rxjs';

const source = interval(500).pipe(take(5));

/*
  interval is emitting a value every 0.5s.  This value is then being mapped to interval that
  is delayed for 1.0s.  The mergeAll operator takes an optional argument that determines how
  many inner observables to subscribe to at a time.  The rest of the observables are stored
  in a backlog waiting to be subscribe.
*/
const example = source
  .pipe(
    map(val => source.pipe(delay(1000), take(3))),
    mergeAll(2)
  )
  .subscribe(val => console.log(val));
/*
  The subscription is completed once the operator emits all values.
*/
```

### Additional Resources

* [mergeAll](https://rxjs.dev/api/operators/mergeAll) 📰 - Official docs
* [Flatten a higher order observable with mergeAll in RxJS](https://egghead.io/lessons/rxjs-flatten-a-higher-order-observable-with-mergeall-in-rxjs?course=use-higher-order-observables-in-rxjs-effectively) 🎥 💵 - André Staltz

***

> 📁 Source Code: <https://github.com/ReactiveX/rxjs/blob/master/packages/rxjs/src/internal/operators/mergeAll.ts>


# pairwise

#### signature: `pairwise(): Observable<Array>`

## Emit the previous and current values as an array.

### Why use pairwise?

The pairwise operator is best suited when you need to compare or perform calculations between the current and previous values emitted by an observable. Real-world examples can be seen in scenarios like tracking mouse movement, where the previous and current positions are used to determine the direction or speed of the cursor, or in financial applications, where consecutive stock price updates are compared to calculate the change or percentage change.

Keep in mind that `pairwise` will not emit an initial value until the observable emits at least two values. This behavior can lead to confusion, as there will be no output and no error, but the observable might not be functioning as intended or is waiting for more values.

Lastly, if you're working with observables that emit multiple values but you only want to compare the last two emitted values, consider using the [bufferCount](/learn-rxjs/operators/transformation/buffercount) operator with a buffer size of 2 and a start buffer count of 1 as an alternative approach.

### Examples

**Example 1:**

( [StackBlitz](https://stackblitz.com/edit/typescript-tkuydr?file=index.ts\&devtoolsheight=50))

```js
// RxJS v6+
import { pairwise, take } from 'rxjs/operators';
import { interval } from 'rxjs';

//Returns: [0,1], [1,2], [2,3], [3,4], [4,5]
interval(1000)
  .pipe(pairwise(), take(5))
  .subscribe(console.log);
```

### Additional Resources

* [pairwise](https://rxjs.dev/api/operators/pairwise) 📰 - Official docs

***

> 📁 Source Code: <https://github.com/ReactiveX/rxjs/blob/master/packages/rxjs/src/internal/operators/pairwise.ts>


# race

#### signature: `race(): Observable`

## The observable to emit first is used.

### Why use race?

The `race` operator is the go-to choice when you want to work with multiple observables that compete against each other, and you're only interested in the first one to emit a value. It's like a competitive race, where the first runner to cross the finish line claims the victory, and the others don't matter anymore (if you're not first you're last?).

A relatable example of using `race` can be observed in an image loading scenario. Imagine you have two sources to load an image from, and you want to display the image as soon as possible. You can use the race operator to subscribe to both sources, and once the first source successfully loads the image, it will emit the value, and the subscription to the other source will be automatically unsubscribed.

It's crucial to remember that `race` only pays attention to the first emitted value from the competing observables. Once an observable wins the race, the other observables are disregarded, and their potential future emissions will have no impact on the output.

If your use case involves working with multiple observables that should all emit values and complete, or you need to process the emitted values in a specific order, consider using operators like [combineLatest](/learn-rxjs/operators/combination/combinelatest) or [forkJoin](/learn-rxjs/operators/combination/forkjoin) instead.

### Examples

**Example 1: race with 4 observables**

( [StackBlitz](https://stackblitz.com/edit/typescript-cvfmug?file=index.ts\&devtoolsheight=100) | [jsBin](http://jsbin.com/goqiwobeno/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/8jcmb1ec/) )

```js
// RxJS v6+
import { mapTo } from 'rxjs/operators';
import { interval } from 'rxjs/observable/interval';
import { race } from 'rxjs/observable/race';

//take the first observable to emit
const example = race(
  //emit every 1.5s
  interval(1500),
  //emit every 1s
  interval(1000).pipe(mapTo('1s won!')),
  //emit every 2s
  interval(2000),
  //emit every 2.5s
  interval(2500)
);
//output: "1s won!"..."1s won!"...etc
const subscribe = example.subscribe(val => console.log(val));
```

**Example 2: race with an error**

( [StackBlitz](https://stackblitz.com/edit/typescript-in6fw6?file=index.ts\&devtoolsheight=100) | [jsFiddle](https://jsfiddle.net/gbeL4t55/2/) )

```js
// RxJS v6+
import { delay, map } from 'rxjs/operators';
import { of, race } from 'rxjs';

//Throws an error and ignores the other observables.
const first = of('first').pipe(
  delay(100),
  map(_ => {
    throw 'error';
  })
);
const second = of('second').pipe(delay(200));
const third = of('third').pipe(delay(300));
// nothing logged
race(first, second, third).subscribe(val => console.log(val));
```

### Additional Resources

* [race](http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#instance-method-race) 📰 - Official docs

***

> 📁 Source Code: <https://github.com/ReactiveX/rxjs/blob/master/packages/rxjs/src/internal/operators/race.ts>


# startWith

#### signature: `startWith(an: Values): Observable`

## Emit given value first.

***

💡 A [BehaviorSubject](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/subjects/behaviorsubject.md) can also start with an initial value!

***

### Why use startWith?

The `startWith` operator is a great tool when you need to provide an initial value to an observable sequence, ensuring that the consumer always receives a value upon subscription. It's a handy way to set a default state or value for your observables, making it easier for subscribers to handle the data and minimizing the chances of encountering unexpected scenarios.

A real-world example can be seen in a search functionality, where the search results should display a list of popular items as a default state before the user starts typing their query. By using startWith, you can seamlessly provide this default data to your subscribers.

Keep in mind that startWith emits the initial value immediately upon subscription. This behavior is helpful when you want to make sure your subscribers receive a value right away, even before the source observable starts emitting values.

### Examples

( [example tests](https://github.com/btroncone/learn-rxjs/blob/master/operators/specs/combination/startwith-spec.ts) )

**Example 1: startWith on number sequence**

( [StackBlitz](https://stackblitz.com/edit/typescript-2qrwjt?file=index.ts\&devtoolsheight=100) | [jsBin](http://jsbin.com/lezuravizu/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/e8dn3ggp/) )

```js
// RxJS v6+
import { startWith } from 'rxjs/operators';
import { of } from 'rxjs';

//emit (1,2,3)
const source = of(1, 2, 3);
//start with 0
const example = source.pipe(startWith(0));
//output: 0,1,2,3
const subscribe = example.subscribe(val => console.log(val));
```

**Example 2: startWith for initial scan value**

( [StackBlitz](https://stackblitz.com/edit/typescript-8gkbsc?file=index.ts\&devtoolsheight=100) | | [jsBin](http://jsbin.com/gemevuzoha/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/54r3g83e/) )

```js
// RxJS v6+
import { startWith, scan } from 'rxjs/operators';
import { of } from 'rxjs';

//emit ('World!', 'Goodbye', 'World!')
const source = of('World!', 'Goodbye', 'World!');
//start with 'Hello', concat current string to previous
const example = source.pipe(
  startWith('Hello'),
  scan((acc, curr) => `${acc} ${curr}`)
);
/*
  output:
  "Hello"
  "Hello World!"
  "Hello World! Goodbye"
  "Hello World! Goodbye World!"
*/
const subscribe = example.subscribe(val => console.log(val));
```

**Example 3: startWith multiple values**

( [StackBlitz](https://stackblitz.com/edit/typescript-ek45ff?file=index.ts\&devtoolsheight=100) | [jsBin](http://jsbin.com/cumupemuxa/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/ckcyj3ms/) )

```js
// RxJS v6+
import { startWith } from 'rxjs/operators';
import { interval } from 'rxjs';

//emit values in sequence every 1s
const source = interval(1000);
//start with -3, -2, -1
const example = source.pipe(startWith(-3, -2, -1));
//output: -3, -2, -1, 0, 1, 2....
const subscribe = example.subscribe(val => console.log(val));
```

### Related Recipes

* [Alphabet Invasion Game](/learn-rxjs/recipes/alphabet-invasion-game)
* [Breakout Game](/learn-rxjs/recipes/breakout-game)
* [Car Racing Game](/learn-rxjs/recipes/car-racing-game)
* [Platform Jumper Game](/learn-rxjs/recipes/platform-jumper-game)
* [Smart Counter](/learn-rxjs/recipes/smartcounter)
* [Space Invaders Game](/learn-rxjs/recipes/space-invaders-game)
* [Stop Watch](/learn-rxjs/recipes/stop-watch)
* [Tank Battle Game](/learn-rxjs/recipes/tank-battle-game)
* [Tetris Game](/learn-rxjs/recipes/tetris-game)
* [Uncover Image Game](/learn-rxjs/recipes/uncover-image-game)

### Additional Resources

* [startWith](https://rxjs.dev/api/operators/startWith) 📰 - Official docs
* [Displaying initial data with startWith](https://egghead.io/lessons/rxjs-displaying-initial-data-with-startwith?course=step-by-step-async-javascript-with-rxjs) 🎥 💵 - John Linquist
* [Clear data while loading with startWith](https://egghead.io/lessons/rxjs-reactive-programming-clear-data-while-loading-with-rxjs-startwith?course=introduction-to-reactive-programming) 🎥 💵 - André Staltz
* [Combination operator: concat, startWith](https://egghead.io/lessons/rxjs-combination-operators-concat-startwith?course=rxjs-beyond-the-basics-operators-in-depth) 🎥 💵 - André Staltz

***

> 📁 Source Code: <https://github.com/ReactiveX/rxjs/blob/master/packages/rxjs/src/internal/operators/startWith.ts>


# withLatestFrom

#### signature: `withLatestFrom(other: Observable, project: Function): Observable`

## Also provide the last value from another observable.

***

💡 If you want the last emission any time a variable number of observables emits, try [combinelatest](/learn-rxjs/operators/combination/combinelatest)!

***

### Why use withLatestFrom?

The `withLatestFrom` operator is your best friend when you have one main observable whose emissions depend on the latest values from one or more other observables. Think of it as a one-way data flow, where the primary observable takes the lead and other observables chime in with their most recent values.

A classic example to remember `withLatestFrom` is a chat application that needs to send a message with a user's current location. The message sending event (main observable) combines with the latest location data (another observable) to form the final message object.

Keep in mind that `withLatestFrom` only emits a value when the main observable emits, and after each additional observable has emitted at least once. This can catch you off guard, as you might not see any output or errors while one of the observables isn't behaving as expected, or a subscription is delayed.

If you need to combine values from multiple observables that emit more than once and are interdependent, consider using [`combineLatest`](/learn-rxjs/operators/combination/combinelatest) instead. And for scenarios where observables emit only once or you just need their last values, [`forkJoin`](/learn-rxjs/operators/combination/forkjoin) might be a more suitable choice.

### Examples

**Example 1: Latest value from quicker second source**

( [StackBlitz](https://stackblitz.com/edit/typescript-tznzbj?file=index.ts\&devtoolsheight=100) | [jsBin](http://jsbin.com/fitekeseru/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/9c3pfgpk/) )

```js
// RxJS v6+
import { withLatestFrom, map } from 'rxjs/operators';
import { interval } from 'rxjs';

//emit every 5s
const source = interval(5000);
//emit every 1s
const secondSource = interval(1000);
const example = source.pipe(
  withLatestFrom(secondSource),
  map(([first, second]) => {
    return `First Source (5s): ${first} Second Source (1s): ${second}`;
  })
);
/*
  "First Source (5s): 0 Second Source (1s): 4"
  "First Source (5s): 1 Second Source (1s): 9"
  "First Source (5s): 2 Second Source (1s): 14"
  ...
*/
const subscribe = example.subscribe(val => console.log(val));
```

**Example 2: Slower second source**

( [StackBlitz](https://stackblitz.com/edit/typescript-gigsdv?file=index.ts\&devtoolsheight=100) | [jsBin](http://jsbin.com/vujekucuxa/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/bywLL579/) )

```js
// RxJS v6+
import { withLatestFrom, map } from 'rxjs/operators';
import { interval } from 'rxjs';

//emit every 5s
const source = interval(5000);
//emit every 1s
const secondSource = interval(1000);
//withLatestFrom slower than source
const example = secondSource.pipe(
  //both sources must emit at least 1 value (5s) before emitting
  withLatestFrom(source),
  map(([first, second]) => {
    return `Source (1s): ${first} Latest From (5s): ${second}`;
  })
);
/*
  "Source (1s): 4 Latest From (5s): 0"
  "Source (1s): 5 Latest From (5s): 0"
  "Source (1s): 6 Latest From (5s): 0"
  ...
*/
const subscribe = example.subscribe(val => console.log(val));
```

### Related Recipes

* [Progress Bar](/learn-rxjs/recipes/progressbar)
* [Game Loop](/learn-rxjs/recipes/gameloop)
* [Space Invaders Game](/learn-rxjs/recipes/space-invaders-game)
* [Uncover Image Game](/learn-rxjs/recipes/uncover-image-game)

### Additional Resources

* [withLatestFrom](https://rxjs.dev/api/operators/withLatestFrom) 📰 - Official docs
* [Combination operator: withLatestFrom](https://egghead.io/lessons/rxjs-combination-operator-withlatestfrom?course=rxjs-beyond-the-basics-operators-in-depth) 🎥 💵 - André Staltz

***

> 📁 Source Code: <https://github.com/ReactiveX/rxjs/blob/master/packages/rxjs/src/internal/operators/withLatestFrom.ts>


# zip

#### signature: `zip(observables: *): Observable`

## After all observables emit, emit values as an array

***

💡 Combined with [interval](/learn-rxjs/operators/creation/interval) or [timer](/learn-rxjs/operators/creation/timer), zip can be used to time output from another source!

***

### Why use zip?

This operator is ideal when you want to combine values from multiple observables in a pairwise fashion, like zipping together the teeth of a zipper. Imagine having two observables, where one emits values like "hot", "warm", "cold", and the other emits values like "coffee", "tea", "lemonade". Using the zip operator, you'd pair them together as "hot coffee", "warm tea", and "cold lemonade".

An everyday example is when you want to match information from two sources, like pairing names with their corresponding scores in a game. Picture an observable emitting player names and another emitting their scores. With zip, you can easily create pairs of `[player, score]`, ensuring each player is associated with the correct score.

Be mindful that zip will only emit a value when all input observables have emitted a corresponding value. This means if one observable has emitted more values than another, the unmatched values will be held back until the other observable emits its next value. In some cases, this could lead to unpaired values, making it important to ensure your observables are synchronized.

### Examples

**Example 1: zip multiple observables emitting at alternate intervals**

( [StackBlitz](https://stackblitz.com/edit/typescript-5az27c?file=index.ts\&devtoolsheight=100) | [jsBin](http://jsbin.com/lireyisira/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/ton462sg/) )

```js
// RxJS v6+
import { delay } from 'rxjs/operators';
import { of, zip } from 'rxjs';

const sourceOne = of('Hello');
const sourceTwo = of('World!');
const sourceThree = of('Goodbye');
const sourceFour = of('World!');
//wait until all observables have emitted a value then emit all as an array
const example = zip(
  sourceOne,
  sourceTwo.pipe(delay(1000)),
  sourceThree.pipe(delay(2000)),
  sourceFour.pipe(delay(3000))
);
//output: ["Hello", "World!", "Goodbye", "World!"]
const subscribe = example.subscribe(val => console.log(val));
```

**Example 2: zip when 1 observable completes**

( [StackBlitz](https://stackblitz.com/edit/typescript-f4qgry?file=index.ts\&devtoolsheight=100) | [jsBin](http://jsbin.com/fisitatesa/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/oamyk3xr/) )

```js
// RxJS v6+
import { take } from 'rxjs/operators';
import { interval, zip } from 'rxjs';

//emit every 1s
const source = interval(1000);
//when one observable completes no more values will be emitted
const example = zip(source, source.pipe(take(2)));
//output: [0,0]...[1,1]
const subscribe = example.subscribe(val => console.log(val));
```

**Example 3: get X/Y coordinates of drag start/finish (mouse down/up)**

( [StackBlitz](https://stackblitz.com/edit/rxjs-zip-mousedownup-coordinates?file=index.ts\&devtoolsheight=50) )

```js
// RxJS v6+
import { fromEvent, zip } from 'rxjs';
import { map } from 'rxjs/operators';

const documentEvent = eventName =>
  fromEvent(document, eventName).pipe(
    map((e: MouseEvent) => ({ x: e.clientX, y: e.clientY }))
  );

zip(documentEvent('mousedown'), documentEvent('mouseup')).subscribe(e =>
  console.log(JSON.stringify(e))
);
```

**Example 4: mouse click duration**

( [StackBlitz](https://stackblitz.com/edit/rxjs-zip-mouseclickduration?file=index.ts\&devtoolsheight=50) )

```js
// RxJS v6+
import { fromEvent, zip } from 'rxjs';
import { map } from 'rxjs/operators';

const eventTime = eventName =>
  fromEvent(document, eventName).pipe(map(() => new Date()));

const mouseClickDuration = zip(
  eventTime('mousedown'),
  eventTime('mouseup')
).pipe(map(([start, end]) => Math.abs(start.getTime() - end.getTime())));

mouseClickDuration.subscribe(console.log);
```

### Additional Resources

* [zip](http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#static-method-zip) 📰 - Official docs
* [Combination operator: zip](https://egghead.io/lessons/rxjs-combination-operator-zip?course=rxjs-beyond-the-basics-operators-in-depth) 🎥 💵 - André Staltz

***

> 📁 Source Code: <https://github.com/ReactiveX/rxjs/blob/master/packages/rxjs/src/internal/operators/zip.ts>


# Conditional

For use-cases that depend on a specific condition to be met, these operators do the trick.

## Contents

* [defaultIfEmpty](/learn-rxjs/operators/conditional/defaultifempty)
* [every](/learn-rxjs/operators/conditional/every)
* [iif](/learn-rxjs/operators/conditional/iif)
* [sequenceequal](/learn-rxjs/operators/conditional/sequenceequal)


# defaultIfEmpty

#### signature: `defaultIfEmpty(defaultValue: any): Observable`

## Emit given value if nothing is emitted before completion.

### Examples

**Example 1: Default for empty value**

( [Stackblitz](https://stackblitz.com/edit/typescript-3btzml?file=index.ts\&devtoolsheight=100) | [jsBin](http://jsbin.com/yawumoqatu/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/8ex96cov/) )

```js
// RxJS v6+
import { defaultIfEmpty } from 'rxjs/operators';
import { of } from 'rxjs';

//emit 'Observable.of() Empty!' when empty, else any values from source
const exampleOne = of().pipe(defaultIfEmpty('Observable.of() Empty!'));
//output: 'Observable.of() Empty!'
const subscribe = exampleOne.subscribe(val => console.log(val));
```

**Example 2: Default for Observable.empty**

( [Stackblitz](https://stackblitz.com/edit/typescript-tyfjhu?file=index.ts\&devtoolsheight=100) | [jsBin](http://jsbin.com/kojafuvesu/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/3edw828p/) )

```js
// RxJS v6+
import { defaultIfEmpty } from 'rxjs/operators';
import { empty } from 'rxjs';

//emit 'Observable.empty()!' when empty, else any values from source
const example = empty().pipe(defaultIfEmpty('Observable.empty()!'));
//output: 'Observable.empty()!'
const subscribe = example.subscribe(val => console.log(val));
```

### Additional Resources

* [defaultIfEmpty](https://rxjs.dev/api/operators/defaultIfEmpty) 📰 - Official docs

***

> 📁 Source Code: <https://github.com/ReactiveX/rxjs/blob/master/packages/rxjs/src/internal/operators/defaultIfEmpty.ts>


# every

#### signature: `every(predicate: function, thisArg: any): Observable`

## If all values pass predicate before completion emit true, else false.

### Examples

**Example 1: Some values false**

( [Stackblitz](https://stackblitz.com/edit/typescript-299d7s?file=index.ts\&devtoolsheight=100) | [jsBin](http://jsbin.com/cibijotase/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/1b46tsm7/) )

```js
// RxJS v6+
import { every } from 'rxjs/operators';
import { of } from 'rxjs';

//emit 5 values
const source = of(1, 2, 3, 4, 5);
const example = source.pipe(
  //is every value even?
  every(val => val % 2 === 0)
);
//output: false
const subscribe = example.subscribe(val => console.log(val));
```

**Example 2: All values true**

( [Stackblitz](https://stackblitz.com/edit/typescript-ztrzqe?file=index.ts\&devtoolsheight=100) | [jsBin](http://jsbin.com/yuxefiviko/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/x34nLmcj/) )

```js
// RxJS v6+
import { every } from 'rxjs/operators';
import { of } from 'rxjs';

//emit 5 values
const allEvens = of(2, 4, 6, 8, 10);
const example = allEvens.pipe(
  //is every value even?
  every(val => val % 2 === 0)
);
//output: true
const subscribe = example.subscribe(val => console.log(val));
```

**Example 3: Values arriving over time and completing stream prematurely due to every returning false**

( [Stackblitz](https://stackblitz.com/edit/rxjs-every-example?file=index.ts\&devtoolsheight=100) )

```js
// RxJS v6+
console.clear();
import { concat, of } from 'rxjs';
import { every, delay, tap } from 'rxjs/operators';

const log = console.log;
const returnCode = request => (Number.isInteger(request) ? 200 : 400);
const fakeRequest = request =>
  of({ code: returnCode(request) }).pipe(
    tap(_ => log(request)),
    delay(1000)
  );

const apiCalls$ = concat(
  fakeRequest(1),
  fakeRequest('invalid payload'),
  fakeRequest(2) //this won't execute as every will return false for previous line
).pipe(
  every(e => e.code === 200),
  tap(e => log(`all request successful: ${e}`))
);

apiCalls$.subscribe();
```

### Additional Resources

* [every](https://rxjs.dev/api/operators/every) 📰 - Official docs

***

> 📁 Source Code: <https://github.com/ReactiveX/rxjs/blob/master/packages/rxjs/src/internal/operators/every.ts>


# iif

#### signature: `iif(condition: () => boolean, trueResult: SubscribableOrPromise = EMPTY, falseResult: SubscribableOrPromise = EMPTY): Observable`

## Subscribe to first or second observable based on a condition

### Examples

**Example 1: simple iif**

( [Stackblitz](https://stackblitz.com/edit/rxjs-iif?file=index.ts\&devtoolsheight=100) )

```js
// RxJS v6+
import { iif, of, interval } from 'rxjs';
import { mergeMap } from 'rxjs/operators';

const r$ = of('R');
const x$ = of('X');

interval(1000)
  .pipe(mergeMap(v => iif(() => v % 4 === 0, r$, x$)))
  .subscribe(console.log);

// output: R, X, X, X, R, X, X, X, etc...
```

**Example 2: iif with mouse moves**

( [Stackblitz](https://stackblitz.com/edit/rxjs-iif-mousemoves?file=index.ts?file=index.ts\&devtoolsheight=50) )

```js
// RxJS v6+
import { fromEvent, iif, of } from 'rxjs';
import { mergeMap, map, throttleTime, filter } from 'rxjs/operators';

const r$ = of(`I'm saying R!!`);
const x$ = of(`X's always win!!`);

fromEvent(document, 'mousemove')
  .pipe(
    throttleTime(50),
    filter((move: MouseEvent) => move.clientY < 210),
    map((move: MouseEvent) => move.clientY),
    mergeMap(yCoord => iif(() => yCoord < 110, r$, x$))
  )
  .subscribe(console.log);
```

**Example 3: iif with default**

( [Stackblitz](https://stackblitz.com/edit/rxjs-iif-pqmw2f?file=index.ts?file=index.ts\&devtoolsheight=100) )

```js
// RxJS v6+
import { fromEvent, iif, of, interval, pipe } from 'rxjs';
import { mergeMap } from 'rxjs/operators';

interval(1000)
  .pipe(
    mergeMap(v =>
      iif(
        () => !!(v % 2),
        of(v)
        // if not supplied defaults to EMPTY
      )
    )
    // output: 1,3,5...
  )
  .subscribe(console.log);
```

### Related Recipes

* [Swipe To Refresh](/learn-rxjs/recipes/swipe-to-refresh)

### Additional Resources

* [iif](https://rxjs.dev/api/index/function/iif) 📰 - Official docs

***

> 📁 Source Code: <https://github.com/ReactiveX/rxjs/blob/master/src/internal/observable/iif.ts>


# sequenceEqual

#### signature: `sequenceEqual(compareTo: Observable, comparor?: (a, b) => boolean): Observable`

## Compares emitted sequence to expected sequence for match

### Examples

**Example 1: simple sequenceEqual**

( [Stackblitz](https://stackblitz.com/edit/rxjs-sequenceequal?file=index.ts\&devtoolsheight=100) )

```js
// RxJS v6+
import { of, from } from 'rxjs';
import { sequenceEqual, switchMap } from 'rxjs/operators';

const expectedSequence = from([4, 5, 6]);

of([1, 2, 3], [4, 5, 6], [7, 8, 9])
  .pipe(switchMap(arr => from(arr).pipe(sequenceEqual(expectedSequence))))
  .subscribe(console.log);

//output: false, true, false
```

**Example 2: sequenceEqual with keyboard events**

( [Stackblitz](https://stackblitz.com/edit/rxjs-sequenceequal-buffercount?file=index.ts\&devtoolsheight=50) )

```js
// RxJS v6+
import { from, fromEvent } from 'rxjs';
import { sequenceEqual, map, bufferCount, mergeMap, tap } from 'rxjs/operators';

const expectedSequence = from(['q', 'w', 'e', 'r', 't', 'y']);
const setResult = text => (document.getElementById('result').innerText = text);

fromEvent(document, 'keydown')
  .pipe(
    map((e: KeyboardEvent) => e.key),
    tap(v => setResult(v)),
    bufferCount(6),
    mergeMap(keyDowns =>
      from(keyDowns).pipe(
        sequenceEqual(expectedSequence),
        tap(isItQwerty => setResult(isItQwerty ? 'WELL DONE!' : 'TYPE AGAIN!'))
      )
    )
  )
  .subscribe(e => console.log(`did you say qwerty? ${e}`));
```

### Related Recipes

* [Lockscreen](/learn-rxjs/recipes/lockscreen)
* [Memory Game](/learn-rxjs/recipes/memory-game)

### Additional Resources

* [sequenceEqual](https://rxjs.dev/api/operators/sequenceEqual) 📰 - Official docs

***

> 📁 Source Code: <https://github.com/ReactiveX/rxjs/blob/master/packages/rxjs/src/internal/operators/sequenceEqual.ts>


# Creation

These operators allow the creation of an observable from nearly anything. From generic to specific use-cases you are free, and encouraged, to turn [everything into a stream](http://slides.com/robwormald/everything-is-a-stream#/).

## Contents

* [ajax](/learn-rxjs/operators/creation/ajax) ⭐
* [create](/learn-rxjs/operators/creation/create)
* [defer](/learn-rxjs/operators/creation/defer)
* [empty](/learn-rxjs/operators/creation/empty)
* [from](/learn-rxjs/operators/creation/from) ⭐
* [fromEvent](/learn-rxjs/operators/creation/fromevent)
* [generate](/learn-rxjs/operators/creation/generate)
* [interval](/learn-rxjs/operators/creation/interval)
* [of](/learn-rxjs/operators/creation/of) ⭐
* [range](/learn-rxjs/operators/creation/range)
* [throwError](/learn-rxjs/operators/creation/throw)
* [timer](/learn-rxjs/operators/creation/timer)

⭐ - *commonly used*

### Additional Resources

* [Creating Observables From Scratch](https://egghead.io/courses/rxjs-beyond-the-basics-creating-observables-from-scratch) 🎥 💵 - André Staltz


# ajax

#### signature: `ajax(urlOrRequest: string | AjaxRequest)`

## Create an observable for an Ajax request with either a request object with url, headers, etc or a string for a URL.

### Examples

**Example 1: Observable that emits the response object that is being returned from the request.**

( [StackBlitz](https://stackblitz.com/edit/rxjs-raqi89) )

```js
// RxJS v6+
import { ajax } from 'rxjs/ajax';

const githubUsers = `https://api.github.com/users?per_page=2`;

const users = ajax(githubUsers);

const subscribe = users.subscribe(
  res => console.log(res),
  err => console.error(err)
);

/* output
{  
  "originalEvent":{  
    "isTrusted":true
  },
  "xhr":{  

  },
  "request":{  
    "async":true,
    "crossDomain":true,
    "withCredentials":false,
    "headers":{  

    },
    "method":"GET",
    "responseType":"json",
    "timeout":0,
    "url":"https://api.github.com/users?per_page=2"
  },
  "status":200,
  "responseType":"json",
  "response":[  
    {  
      "login":"mojombo",
      "id":1,
      "node_id":"MDQ6VXNlcjE=",
      "avatar_url":"https://avatars0.githubusercontent.com/u/1?v=4",
      "gravatar_id":"",
      ...
    },
    {  
      "login":"defunkt",
      "id":2,
      "node_id":"MDQ6VXNlcjI=",
      "avatar_url":"https://avatars0.githubusercontent.com/u/2?v=4",
      "gravatar_id":"",
      "...
    }
  ]
}
*/
```

**Example 2: Observable that emits only the json key of the response object that is being returned from the request.**

( [StackBlitz](https://stackblitz.com/edit/rxjs-8jkrhl) )

```js
// RxJS v6+
import { ajax } from 'rxjs/ajax';

const githubUsers = `https://api.github.com/users?per_page=2`;

const users = ajax.getJSON(githubUsers);

const subscribe = users.subscribe(
  res => console.log(res),
  err => console.error(err)
);

/* output
[  
  {  
    "login":"mojombo",
    "id":1,
    "node_id":"MDQ6VXNlcjE=",
    "avatar_url":"https://avatars0.githubusercontent.com/u/1?v=4",
    "gravatar_id":"",
    "...
  },
  {  
    "login":"defunkt",
    "id":2,
    "node_id":"MDQ6VXNlcjI=",
    "avatar_url":"https://avatars0.githubusercontent.com/u/2?v=4",
    "gravatar_id":"",
    ...
  }
]
*/
```

**Example 3: Observable that emits the error object that is being returned from the request.**

( [StackBlitz](https://stackblitz.com/edit/rxjs-vnxkth) )

```js
// RxJS v6+
import { ajax } from 'rxjs/ajax';

const githubUsers = `https://api.github.com/error`;

const users = ajax.getJSON(githubUsers);

const subscribe = users.subscribe(
  res => console.log(res),
  err => console.error(err)
);

/* output
Error: ajax error 404
*/
```

**Example 4: Ajax operator with object as input.**

( [StackBlitz](https://stackblitz.com/edit/rxjs-vqnnot) )

```js
// RxJS v6+
import { ajax } from 'rxjs/ajax';

const githubUsers = `https://api.github.com/error`;

const users = ajax({
  url: githubUsers,
  method: 'GET',
  headers: {
    /*some headers*/
  },
  body: {
    /*in case you need a body*/
  }
});

const subscribe = users.subscribe(
  res => console.log(res),
  err => console.error(err)
);
```

### Additional Resources

* [ajax](https://rxjs.dev/api/ajax/ajax) 📰 - Official docs

***

> 📁 Source Code: <https://github.com/ReactiveX/rxjs/blob/6.4.0/src/internal/observable/dom/ajax.ts#L20-L19>


# create

## Deprecated: Use `new Observable()` instead

> ⚠️ **Important**: `Observable.create()` was deprecated in RxJS v6.4.0. Use the `new Observable()` constructor instead.

**signature**: `new Observable(subscribe: (observer: Observer) => TeardownLogic)`

```typescript
new Observable(subscribe: (observer: Observer) => TeardownLogic)
```

Create a custom observable by defining subscription behavior.

***

## 💡 Tips

* **Consider creation operators first**: Before creating a custom observable, check if operators like [defer](/learn-rxjs/operators/creation/defer), [from](/learn-rxjs/operators/creation/from), [fromEvent](/learn-rxjs/operators/creation/fromevent), or [interval](/learn-rxjs/operators/creation/interval) already solve your use case
* **Use for bridging non-reactive APIs**: Custom observables shine when wrapping callbacks, event emitters, WebSockets, or other non-observable data sources
* **Always return teardown logic**: Return a cleanup function to prevent memory leaks when subscriptions end

***

## Why use a custom observable?

Custom observables are your bridge between the non-reactive world and RxJS. Think of them as adapters—when you have a data source that doesn't speak "Observable" (like a WebSocket connection, a third-party library with callbacks, or a browser API like Geolocation), creating a custom observable lets you wrap it up and make it play nicely with the rest of your reactive code.

Here's the thing: **you'll rarely need to create custom observables**. RxJS already provides creation operators for most common scenarios. Timers, events, promises, arrays, and more. But when you encounter an API that doesn't fit any existing operator, custom observables give you fine-grained control. You decide exactly when to emit values (observer.next()), how to handle errors (observer.error()), and what cleanup should happen when someone unsubscribes.

One way to think about this is like writing a translator. The non-reactive API speaks one language, your Observable streams speak another, and your custom observable sits in the middle making sure they understand each other. When implementing [the cleanup function](#example-2-observable-with-proper-cleanup), remember that this is your chance to be a good citizen. Close connections, cancel timers, remove listeners. It's like turning off the lights when you leave a room.

In essence, custom observables are powerful but should be used sparingly. If an existing creation operator can do the job, use that. But when you need that extra control—when you're integrating with legacy code, third-party libraries, or unusual data sources, this is your tool.

***

## Examples

### Example 1: Simple custom observable that emits multiple values

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

```typescript
// RxJS v6+
import { Observable } from 'rxjs';

/*
  Create an observable that emits 'Hello' and 'World' on subscription.
  Note: Using the modern constructor syntax, not the deprecated Observable.create()
*/
const hello$ = new Observable(observer => {
  observer.next('Hello');
  observer.next('World');
  observer.complete();
});

// Output: 'Hello'...'World'
const subscription = hello$.subscribe(val => console.log(val));
```

### Example 2: Observable with proper cleanup

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

```typescript
// RxJS v6+
import { Observable } from 'rxjs';

/*
  Create an observable that emits even numbers every second.
  Demonstrates the importance of returning a teardown function.
*/
const evenNumbers$ = new Observable(observer => {
  let value = 0;
  
  const intervalId = setInterval(() => {
    if (value % 2 === 0) {
      observer.next(value);
    }
    value++;
  }, 1000);
  
  // Return cleanup function - called when unsubscribe() is invoked
  return () => {
    console.log('Cleaning up interval');
    clearInterval(intervalId);
  };
});

// Output: 0...2...4...6...8
const subscription = evenNumbers$.subscribe(val => console.log(val));

// Unsubscribe after 10 seconds - triggers cleanup
setTimeout(() => {
  subscription.unsubscribe();
}, 10000);
```

### Example 3: Wrapping a callback-based API

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

```typescript
// RxJS v6+
import { Observable } from 'rxjs';

/*
  Wrap the browser's Geolocation API into an observable.
  This demonstrates how custom observables bridge non-reactive APIs.
*/
function getCurrentPosition(): Observable<GeolocationPosition> {
  return new Observable(observer => {
    // Check if geolocation is available
    if (!navigator.geolocation) {
      observer.error(new Error('Geolocation not supported'));
      return;
    }
    
    // Get position and emit it
    const watchId = navigator.geolocation.watchPosition(
      position => observer.next(position),
      error => observer.error(error),
      { enableHighAccuracy: true }
    );
    
    // Return cleanup to stop watching position when unsubscribed
    return () => {
      navigator.geolocation.clearWatch(watchId);
    };
  });
}

// Usage
const position$ = getCurrentPosition();
const subscription = position$.subscribe({
  next: position => {
    console.log('Latitude:', position.coords.latitude);
    console.log('Longitude:', position.coords.longitude);
  },
  error: err => console.error('Error getting position:', err)
});

// Stop watching after 30 seconds
setTimeout(() => subscription.unsubscribe(), 30000);
```

### Example 4: Creating an observable from a WebSocket

```typescript
// RxJS v6+
import { Observable } from 'rxjs';

/*
  Wrap a WebSocket connection in an observable.
  Demonstrates managing complex async resources with proper cleanup.
*/
function createWebSocketObservable(url: string): Observable<MessageEvent> {
  return new Observable(observer => {
    const socket = new WebSocket(url);
    
    socket.onopen = () => {
      console.log('WebSocket connected');
    };
    
    socket.onmessage = (event) => {
      observer.next(event);
    };
    
    socket.onerror = (error) => {
      observer.error(error);
    };
    
    socket.onclose = () => {
      observer.complete();
    };
    
    // Cleanup: close the socket when unsubscribed
    return () => {
      if (socket.readyState === WebSocket.OPEN) {
        socket.close();
      }
    };
  });
}

// Usage
const messages$ = createWebSocketObservable('wss://example.com/socket');
const subscription = messages$.subscribe({
  next: event => console.log('Message received:', event.data),
  error: err => console.error('WebSocket error:', err),
  complete: () => console.log('WebSocket closed')
});

// Close connection after 60 seconds
setTimeout(() => subscription.unsubscribe(), 60000);
```

***

## Related Recipes

* [Smart Counter](/learn-rxjs/recipes/smartcounter)

***

## Additional Resources

* [Observable](https://rxjs.dev/api/index/class/Observable) 📰 - Official docs
* [Observable Constructor](https://rxjs.dev/api/index/class/Observable#constructor) 📰 - Official constructor docs

***

**📁 Source Code:** <https://github.com/ReactiveX/rxjs/blob/master/packages/observable/src/observable.ts>


# defer

#### signature: `defer(observableFactory: function(): SubscribableOrPromise): Observable`

## Create an observable with given subscription function.

***

💡 [`defer`](https://github.com/ReactiveX/rxjs/blob/ecc73d2a1564d0d3edffba90eec76510e509236c/src/internal/observable/iif.ts#L94-L100) is used as part of the [`iif`](/learn-rxjs/operators/conditional/iif) operator!

***

### Examples

**Example 1: Defer to get current date/time at the time of subscription**

( [StackBlitz](https://stackblitz.com/edit/rxjs-defer-example?file=index.ts\&devtoolsheight=100) )

```js
// RxJS v6+
import { defer, of, timer, merge } from 'rxjs';
import { switchMap } from 'rxjs/operators';

const s1 = of(new Date()); //will capture current date time
const s2 = defer(() => of(new Date())); //will capture date time at the moment of subscription

console.log(new Date());

timer(2000)
  .pipe(switchMap(_ => merge(s1, s2)))
  .subscribe(console.log);

/*
OUTPUT => 
2019-02-10T12:38:30.000Z (currrent date/time from first console log)
2019-02-10T12:38:30.000Z (date/time in s1 console log, captured date/time at the moment of observable creation)
2019-02-10T12:38:32.000Z (date/time in s2 console log, captured date/time at the moment of subscription)
*/

/*//NOTE: 'traditional' js equivalent of timer code above is:
setTimeout(() => {
  s1.subscribe(console.log);
  s2.subscribe(console.log);
}, 2000);
*/
```

### Related Recipes

* [Save Indicator](/learn-rxjs/recipes/save-indicator)

### Additional Resources

* [defer](https://rxjs.dev/api/index/function/defer) 📰 - Official docs

***

> 📁 Source Code: <https://github.com/ReactiveX/rxjs/blob/master/src/internal/observable/defer.ts>


# empty

#### signature: `empty(scheduler: Scheduler): Observable`

## Observable that immediately completes.

### Examples

**Example 1: empty immediately completes**

( [StackBlitz](https://stackblitz.com/edit/typescript-aqfpkq?file=index.ts\&devtoolsheight=100) | [jsBin](http://jsbin.com/rodubucaqa/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/bz71mzuy/) )

```js
// RxJS v6+
import { empty } from 'rxjs';

//output: 'Complete!'
const subscribe = empty().subscribe({
  next: () => console.log('Next'),
  complete: () => console.log('Complete!')
});
```

**Example 2: `empty` with timer**

( [StackBlitz](https://stackblitz.com/edit/typescript-uujo8t?file=index.ts\&devtoolsheight=50) )

```js
// RxJS v6+
import { interval, fromEvent, merge, empty } from 'rxjs';
import { switchMap, scan, takeWhile, startWith, mapTo } from 'rxjs/operators';

const countdownSeconds = 10;
const setHTML = id => val => (document.getElementById(id).innerHTML = val);
const pauseButton = document.getElementById('pause');
const resumeButton = document.getElementById('resume');
const interval$ = interval(1000).pipe(mapTo(-1));

const pause$ = fromEvent(pauseButton, 'click').pipe(mapTo(false));
const resume$ = fromEvent(resumeButton, 'click').pipe(mapTo(true));

const timer$ = merge(pause$, resume$)
  .pipe(
    startWith(true),
    // if timer is paused return empty observable
    switchMap(val => (val ? interval$ : empty())),
    scan((acc, curr) => (curr ? curr + acc : acc), countdownSeconds),
    takeWhile(v => v >= 0)
  )
  .subscribe(setHTML('remaining'));
```

### Related Recipes

* [Memory Game](/learn-rxjs/recipes/memory-game)
* [Save Indicator](/learn-rxjs/recipes/save-indicator)

### Additional Resources

* [empty](https://rxjs.dev/api/index/function/empty) 📰 - Official docs
* [Creation operators: empty, never, and throw](https://egghead.io/lessons/rxjs-creation-operators-empty-never-throw?course=rxjs-beyond-the-basics-creating-observables-from-scratch) 🎥 💵 - André Staltz

***

> 📁 Source Code: <https://github.com/ReactiveX/rxjs/blob/master/src/internal/observable/EmptyObservable.ts>


# from

\`\`# from

**signature: `from(ish: ObservableInput, mapFn: function, thisArg: any, scheduler: Scheduler): Observable`**

### Turn an array, promise, or iterable into an observable.

***

💡 This operator can be used to convert a promise to an observable!

💡 For arrays and iterables, all contained values will be emitted as a sequence!

💡 This operator can also be used to emit a string as a sequence of characters!

***

#### Examples

**Example 1: Observable from array**

( [StackBlitz](https://stackblitz.com/edit/typescript-sckwsw?file=index.ts\&devtoolsheight=100) | [jsBin](http://jsbin.com/foceyuketi/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/o7kb5e6j/) )

```js
// RxJS v6+
import { from } from 'rxjs';

//emit array as a sequence of values
const arraySource = from([1, 2, 3, 4, 5]);
//output: 1,2,3,4,5
const subscribe = arraySource.subscribe(val => console.log(val));
```

**Example 2: Observable from promise**

( [StackBlitz](https://stackblitz.com/edit/typescript-clpg1f?file=index.ts\&devtoolsheight=100) | [jsBin](http://jsbin.com/tamofinujo/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/2czc5sae/) )

```js
// RxJS v6+
import { from } from 'rxjs';

//emit result of promise
const promiseSource = from(new Promise(resolve => resolve('Hello World!')));
//output: 'Hello World'
const subscribe = promiseSource.subscribe(val => console.log(val));
```

**Example 3: Observable from collection**

( [StackBlitz](https://stackblitz.com/edit/typescript-drfckx?file=index.ts\&devtoolsheight=100) | [jsBin](http://jsbin.com/tezohobudu/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/ae6hu9a8/) )

```js
// RxJS v6+
import { from } from 'rxjs';

//works on js collections
const map = new Map();
map.set(1, 'Hi');
map.set(2, 'Bye');

const mapSource = from(map);
//output: [1, 'Hi'], [2, 'Bye']
const subscribe = mapSource.subscribe(val => console.log(val));
```

**Example 4: Observable from string**

( [StackBlitz](https://stackblitz.com/edit/typescript-19nejh?file=index.ts\&devtoolsheight=100) | [jsBin](http://jsbin.com/wenozubana/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/hfvzjcvL/) )

```js
// RxJS v6+
import { from } from 'rxjs';

//emit string as a sequence
const source = from('Hello World');
//output: 'H','e','l','l','o',' ','W','o','r','l','d'
const subscribe = source.subscribe(val => console.log(val));
```

#### Related Recipes

* [HTTP Polling](/learn-rxjs/recipes/http-polling)
* [Lockscreen](/learn-rxjs/recipes/lockscreen)
* [Memory Game](/learn-rxjs/recipes/memory-game)
* [Progress Bar](/learn-rxjs/recipes/progressbar)

#### Additional Resources

* [from](https://rxjs.dev/api/index/function/from) 📰 - Official docs
* [Creation operators: from, fromArray, fromPromise](https://egghead.io/lessons/rxjs-creation-operators-from-fromarray-frompromise?course=rxjs-beyond-the-basics-creating-observables-from-scratch) 🎥 💵 - André Staltz

***

> 📁 Source Code: <https://github.com/ReactiveX/rxjs/blob/master/src/internal/observable/from.ts>


# fromEvent

#### signature: `fromEvent(target: EventTargetLike, eventName: string, selector: function): Observable`

## Turn event into observable sequence.

### Examples

**Example 1: Observable from mouse clicks**

( [StackBlitz](https://stackblitz.com/edit/typescript-mfyefr?file=index.ts\&devtoolsheight=50) | [jsBin](http://jsbin.com/xikapewoqa/1/edit?js,console,output) | [jsFiddle](https://jsfiddle.net/btroncone/vbLz1pdx/) )

```js
// RxJS v6+
import { fromEvent } from 'rxjs';
import { map } from 'rxjs/operators';

//create observable that emits click events
const source = fromEvent(document, 'click');
//map to string with given event timestamp
const example = source.pipe(map(event => `Event time: ${event.timeStamp}`));
//output (example): 'Event time: 7276.390000000001'
const subscribe = example.subscribe(val => console.log(val));
```

### Related Recipes

* [Alphabet Invasion Game](/learn-rxjs/recipes/alphabet-invasion-game)
* [Battleship Game](/learn-rxjs/recipes/battleship-game)
* [Breakout Game](/learn-rxjs/recipes/breakout-game)
* [Car Racing Game](/learn-rxjs/recipes/car-racing-game)
* [Catch The Dot Game](/learn-rxjs/recipes/catch-the-dot-game)
* [Click Ninja Game](/learn-rxjs/recipes/click-ninja-game)
* [Flappy Bird Game](/learn-rxjs/recipes/flappy-bird-game)
* [Game Loop](/learn-rxjs/recipes/gameloop)
* [Horizontal Scroll Indicator](/learn-rxjs/recipes/horizontal-scroll-indicator)
* [HTTP Polling](/learn-rxjs/recipes/http-polling)
* [Lockscreen](/learn-rxjs/recipes/lockscreen)
* [Memory Game](/learn-rxjs/recipes/memory-game)
* [Mine Sweeper Game](/learn-rxjs/recipes/mine-sweeper-game)
* [Platform Jumper Game](/learn-rxjs/recipes/platform-jumper-game)
* [Progress Bar](/learn-rxjs/recipes/progressbar)
* [Save Indicator](/learn-rxjs/recipes/save-indicator)
* [Smart Counter](/learn-rxjs/recipes/smartcounter)
* [Space Invaders Game](/learn-rxjs/recipes/space-invaders-game)
* [Stop Watch](/learn-rxjs/recipes/stop-watch)
* [Swipe To Refresh](/learn-rxjs/recipes/swipe-to-refresh)
* [Tank Battle Game](/learn-rxjs/recipes/tank-battle-game)
* [Tetris Game](/learn-rxjs/recipes/tetris-game)
* [Type Ahead](/learn-rxjs/recipes/type-ahead)
* [Uncover Image Game](/learn-rxjs/recipes/uncover-image-game)

### Additional Resources

* [fromEvent](https://rxjs.dev/api/index/function/fromEvent) 📰 - Official docs

***

> 📁 Source Code: <https://github.com/ReactiveX/rxjs/blob/master/src/internal/observable/fromEvent.ts>


# generate

#### signature: `generate(initialStateOrOptions: GenerateOptions, condition?: ConditionFunc, iterate?: IterateFunc, resultSelectorOrObservable?: (ResultFunc) | SchedulerLike, scheduler?: SchedulerLike): Observable`

## Generates an observable sequence by running a state-driven loop producing the sequence's elements, using the specified scheduler to send out observer messages.

### Examples

**Example 1: Generate**

( [StackBlitz](https://stackblitz.com/edit/rxjs-generate?file=index.ts\&devtoolsheight=100) )

```js
// RxJS v6+
import { generate } from 'rxjs';

generate(
  2,
  x => x <= 8,
  x => x + 3
).subscribe(console.log);

/*
OUTPUT:
2
5
8
*/
```

**Example 2: Generate with result selector**

( [StackBlitz](https://stackblitz.com/edit/rxjs-generate-result-selector?file=index.ts\&devtoolsheight=100) )

```js
// RxJS v6+
import { generate } from 'rxjs';

generate(
  2,
  x => x <= 38,
  x => x + 3,
  x => '.'.repeat(x)
).subscribe(console.log);

/*
OUTPUT:
..
.....
........
...........
..............
.................
....................
.......................
..........................
.............................
................................
...................................
......................................
*/
```

### Related Recipes

* [Breakout Game](/learn-rxjs/recipes/breakout-game)
* [Memory Game](/learn-rxjs/recipes/memory-game)

### Additional Resources

* [generate](https://rxjs.dev/api/index/function/generate) 📰 - Official docs

***

> 📁 Source Code: <https://github.com/ReactiveX/rxjs/blob/master/src/internal/observable/generate.ts>


# interval

#### signature: `interval(period: number, scheduler: Scheduler): Observable`

## Emit numbers in sequence based on provided timeframe.

### Examples

**Example 1: Emit sequence of values at 1 second interval**

( [StackBlitz](https://stackblitz.com/edit/typescript-ohddud?file=index.ts\&devtoolsheight=100) | [jsBin](http://jsbin.com/vigohomabo/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/x3mrwzr0/) )

```js
// RxJS v6+
import { interval } from 'rxjs';

//emit value in sequence every 1 second
const source = interval(1000);
//output: 0,1,2,3,4,5....
const subscribe = source.subscribe(val => console.log(val));
```

### Related Recipes

* [Alphabet Invasion Game](/learn-rxjs/recipes/alphabet-invasion-game)
* [Battleship Game](/learn-rxjs/recipes/battleship-game)
* [Breakout Game](/learn-rxjs/recipes/breakout-game)
* [Car Racing Game](/learn-rxjs/recipes/car-racing-game)
* [Catch The Dot Game](/learn-rxjs/recipes/catch-the-dot-game)
* [Flappy Bird Game](/learn-rxjs/recipes/flappy-bird-game)
* [Matrix Digital Rain](/learn-rxjs/recipes/matrix-digital-rain)
* [Memory Game](/learn-rxjs/recipes/memory-game)
* [Platform Jumper Game](/learn-rxjs/recipes/platform-jumper-game)
* [Space Invaders Game](/learn-rxjs/recipes/space-invaders-game)
* [Stop Watch](/learn-rxjs/recipes/stop-watch)
* [Tank Battle Game](/learn-rxjs/recipes/tank-battle-game)
* [Tetris Game](/learn-rxjs/recipes/tetris-game)
* [Uncover Image Game](/learn-rxjs/recipes/uncover-image-game)

### Additional Resources

* [interval](https://rxjs.dev/api/index/function/interval) 📰 - Official docs
* [Creation operators: interval and timer](https://egghead.io/lessons/rxjs-creation-operators-interval-and-timer?course=rxjs-beyond-the-basics-creating-observables-from-scratch) 🎥 💵 - André Staltz

***

> 📁 Source Code: <https://github.com/ReactiveX/rxjs/blob/master/src/internal/observable/interval.ts>


# of

#### signature: `of(...values, scheduler: Scheduler): Observable`

## Emit variable amount of values in a sequence and then emits a complete notification.

### Examples

**Example 1: Emitting a sequence of numbers**

( [StackBlitz](https://stackblitz.com/edit/typescript-kbpvmm?file=index.ts\&devtoolsheight=100) | [jsBin](http://jsbin.com/kodixitoji/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/f7b35ayz/) )

```js
// RxJS v6+
import { of } from 'rxjs';
//emits any number of provided values in sequence
const source = of(1, 2, 3, 4, 5);
//output: 1,2,3,4,5
const subscribe = source.subscribe(val => console.log(val));
```

**Example 2: Emitting an object, array, and function**

( [StackBlitz](https://stackblitz.com/edit/typescript-m1jbw9?file=index.ts\&devtoolsheight=100) | [jsBin](http://jsbin.com/xevobujama/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/d9rng4dj/) )

```js
// RxJS v6+
import { of } from 'rxjs';
//emits values of any type
const source = of({ name: 'Brian' }, [1, 2, 3], function hello() {
  return 'Hello';
});
//output: {name: 'Brian'}, [1,2,3], function hello() { return 'Hello' }
const subscribe = source.subscribe(val => console.log(val));
```

### Related Recipes

* [Battleship Game](/learn-rxjs/recipes/battleship-game)
* [Breakout Game](/learn-rxjs/recipes/breakout-game)
* [Car Racing Game](/learn-rxjs/recipes/car-racing-game)
* [Mine Sweeper Game](/learn-rxjs/recipes/mine-sweeper-game)
* [Platform Jumper Game](/learn-rxjs/recipes/platform-jumper-game)
* [Save Indicator](/learn-rxjs/recipes/save-indicator)
* [Swipe To Refresh](/learn-rxjs/recipes/swipe-to-refresh)
* [Tetris Game](/learn-rxjs/recipes/tetris-game)
* [Type Ahead](/learn-rxjs/recipes/type-ahead)

### Additional Resources

* [of](https://rxjs.dev/api/index/function/of) 📰 - Official docs
* [Creation operators: of](https://egghead.io/lessons/rxjs-creation-operator-of?course=rxjs-beyond-the-basics-creating-observables-from-scratch) 🎥 💵 - André Staltz

***

> 📁 Source Code: <https://github.com/ReactiveX/rxjs/blob/master/src/internal/observable/of.ts>


# range

#### signature: `range(start: number, count: number, scheduler: Scheduler): Observable`

## Emit numbers in provided range in sequence.

### Examples

**Example 1: Emit range 1-10**

( [StackBlitz](https://stackblitz.com/edit/typescript-r5zrww?file=index.ts\&devtoolsheight=100) | [jsBin](http://jsbin.com/yalefomage/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/cfvfgwn9/) )

```js
// RxJS v6+
import { range } from 'rxjs';

//emit 1-10 in sequence
const source = range(1, 10);
//output: 1,2,3,4,5,6,7,8,9,10
const example = source.subscribe(val => console.log(val));
```

### Additional Resources

* [range](https://rxjs.dev/api/index/function/range) 📰 - Official docs

***

> 📁 Source Code: <https://github.com/ReactiveX/rxjs/blob/master/src/internal/observable/range.ts>


# throwError

```typescript
throwError(errorOrErrorFactory: (() => any) | any): Observable<never>
```

**Creates an Observable that immediately emits an error notification upon subscription.**

***

💡 **When should you use throwError vs. just throwing an error?**

In most cases within operator callbacks (like `map`, `tap`, `mergeMap`), you can simply use JavaScript's native `throw` statement since RxJS wraps these in try-catch blocks. Use `throwError()` specifically when you need to **return an Observable that errors** - particularly in operators like `switchMap`, `mergeMap`, or `concatMap` where an Observable is expected as the return value.

💡 **Factory function recommended**

As of RxJS 7+, pass a factory function `() => error` rather than the error directly. This creates the error at the moment of subscription, providing better stack traces: `throwError(() => new Error('message'))`.

***

## Why use throwError?

Think of `throwError` as your "error signal generator" - it creates an Observable that does nothing but immediately send out an error signal. It's like having a specialized alarm button: when you press it, it doesn't emit any values or complete normally, it just triggers the error path.

You'll reach for `throwError` when you're working in Observable pipelines where you need to return an Observable, but something has gone wrong and you want to propagate that error downstream. For instance, in a [conditional API call](#example-2-conditional-error-in-switchmap) where you validate input before making a request, or when [implementing retry logic](#example-3-using-throwerror-with-retry-strategy) where you want to signal specific failures.

Here's a key insight: while JavaScript's native `throw` statement works great inside operators like `map` or `tap`, `throwError()` shines when you're in operators that expect you to return an Observable - like `switchMap`, `mergeMap`, or inside a custom creation function. In those cases, just throwing would break the chain; you need to return an error Observable instead. It's the difference between throwing an error in your code versus constructing an Observable that represents an error state.

***

## Examples

### Example 1: Basic error emission

[StackBlitz](https://stackblitz.com/edit/typescript-5d3stz?file=index.ts\&devtoolsheight=100)

```typescript
import { throwError } from 'rxjs';

// Create an observable that immediately emits an error
const error$ = throwError(() => new Error('Something went wrong!'));

// Subscribe to see the error
error$.subscribe({
  next: val => console.log('Next:', val), // Won't be called
  error: err => console.error('Error caught:', err.message),
  complete: () => console.log('Complete!') // Won't be called
});

// Output: "Error caught: Something went wrong!"
```

### Example 2: Conditional error in switchMap

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

```typescript
import { of, throwError } from 'rxjs';
import { mergeMap, catchError } from 'rxjs/operators';

interface User {
  id: number;
  name: string;
}

// Simulate fetching user data
function fetchUser(id: number) {
  return of({ id, name: `User ${id}` });
}

// Validate user ID before fetching - handle errors per item
of(0, 5, -1, 10)
  .pipe(
    mergeMap((id) => {
      // Create the source observable based on validation
      const source$ =
        id <= 0
          ? throwError(() => new Error(`Invalid user ID: ${id}`))
          : fetchUser(id);

      // Handle errors for each item individually
      return source$.pipe(
        catchError((err) => {
          console.error('Caught:', err());
          // Provide fallback user for this item only
          return of({ id: 0, name: 'Guest User' } as User);
        })
      );
    })
  )
  .subscribe((user) => console.log('User:', user.name));

/* Output:
   Caught: Invalid user ID: 0
   User: Guest User
   User: User 5
   Caught: Invalid user ID: -1
   User: Guest User
   User: User 10
*/
```

### Example 3: Using throwError with retry strategy

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

```typescript
import { of, throwError, timer } from 'rxjs';
import { mergeMap, retry, tap } from 'rxjs/operators';

let attemptCount = 0;

// Simulate an unreliable API call
function unreliableApiCall() {
  attemptCount++;
  console.log(`API call attempt #${attemptCount}`);
  
  // Fail first 2 attempts, succeed on 3rd
  return attemptCount < 3
    ? throwError(() => new Error('Network timeout'))
    : of({ data: 'Success!' });
}

// Try the API call with retry logic
of(null).pipe(
  mergeMap(() => unreliableApiCall()),
  retry(2) // Retry up to 2 times on error
).subscribe({
  next: result => console.log('Result:', result.data),
  error: err => console.error('Final error:', err.message)
});

/* Output:
   API call attempt #1
   API call attempt #2
   API call attempt #3
   Result: Success!
*/
```

***

## Related Recipes

* [Smart Counter](https://www.learnrxjs.io/learn-rxjs/recipes/smartcounter)
* [HTTP Polling](https://www.learnrxjs.io/learn-rxjs/recipes/http-polling)

***

## Additional Resources

* [throwError](https://rxjs.dev/api/index/function/throwError) 📰 - Official docs
* [Error Handling in RxJS](https://blog.angular-university.io/rxjs-error-handling/) 📰 - Comprehensive guide

***

📁 **Source Code:** <https://github.com/ReactiveX/rxjs/blob/master/src/internal/observable/throwError.ts>


# timer

#### signature: `timer(initialDelay: number | Date, period: number, scheduler: Scheduler): Observable`

## After given duration, emit numbers in sequence every specified duration.

### Examples

**Example 1: timer emits 1 value then completes**

( [StackBlitz](https://stackblitz.com/edit/typescript-fvkzgg?file=index.ts\&devtoolsheight=100) | [jsBin](http://jsbin.com/pazajanehu/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/vpx0y8fu/) )

```js
// RxJS v6+
import { timer } from 'rxjs';

//emit 0 after 1 second then complete, since no second argument is supplied
const source = timer(1000);
//output: 0
const subscribe = source.subscribe(val => console.log(val));
```

**Example 2: timer emits after 1 second, then every 2 seconds**

( [StackBlitz](https://stackblitz.com/edit/typescript-h9pzxr?file=index.ts\&devtoolsheight=100) | [jsBin](http://jsbin.com/kejidofuje/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/30ddov8j/) )

```js
// RxJS v6+
import { timer } from 'rxjs';

/*
  timer takes a second argument, how often to emit subsequent values
  in this case we will emit first value after 1 second and subsequent
  values every 2 seconds after
*/
const source = timer(1000, 2000);
//output: 0,1,2,3,4,5......
const subscribe = source.subscribe(val => console.log(val));
```

### Related Recipes

* [HTTP Polling](/learn-rxjs/recipes/http-polling)

### Additional Resources

* [timer](https://rxjs.dev/api/index/function/timer) 📰 - Official docs
* [Creation operators: interval and timer](https://egghead.io/lessons/rxjs-creation-operators-interval-and-timer?course=rxjs-beyond-the-basics-creating-observables-from-scratch) 🎥 💵 - André Staltz

***

> 📁 Source Code: <https://github.com/ReactiveX/rxjs/blob/master/src/internal/observable/timer.ts>


# Error Handling

Errors are an unfortunate side-effect of development. These operators provide effective ways to gracefully handle errors and retry logic, should they occur.

## Contents

* [catchError](/learn-rxjs/operators/error_handling/catch) ⭐
* [retry](/learn-rxjs/operators/error_handling/retry)
* [retryWhen](/learn-rxjs/operators/error_handling/retrywhen)

⭐ - *commonly used*


# catch / catchError

## signature: `catchError(project: (err: any, caught: Observable<T>) => ObservableInput<any>): Observable`

### Gracefully handle errors in an observable sequence.

***

💡 Need to retry a failed operation? Check out [**retry**](/learn-rxjs/operators/error_handling/retry) or [**retryWhen**](/learn-rxjs/operators/error_handling/retrywhen)!

💡 For resource cleanup regardless of error, use [**finalize**](/learn-rxjs/operators/utility/finalize)!

⚠ Remember to return an observable from the catchError function!

***

## Why use catchError?

Think of `catchError` as your observable's safety net. When your stream encounters an error, whether from a failed HTTP request, unexpected data, or any other issue, `catchError` gives you a chance to recover gracefully instead of letting your entire observable sequence crash and burn. It's the difference between your app showing a friendly "Something went wrong" message versus a blank screen.

What makes `catchError` particularly valuable is its flexibility in how you respond to errors. You can provide [fallback data from a cache](#example-1-catching-error-from-observable), you can [transform errors into user-friendly messages](#example-2-catching-rejected-promise), or you can even decide to retry the operation (though [`retry`](/learn-rxjs/operators/error_handling/retry) is usually better for that). The key insight is understanding *where* you place `catchError` in your operator chain. Put it at the outer level and your entire stream ends when an error occurs, but place it inside operators like `switchMap` and [only that inner operation fails while your stream continues](#example-3-catching-errors-comparison-when-using-switchmapmergemapconcatmapexhaustmap).

In essence, `catchError` keeps your reactive applications resilient by ensuring that errors are handled on your terms, not left to crash your user experience.

***

## Examples

### Example 1: Catching error from observable

( [StackBlitz](https://stackblitz.com/edit/typescript-auc2u2?file=index.ts\&devtoolsheight=100) )

```js
// RxJS v6+
import { throwError, of } from 'rxjs';
import { catchError } from 'rxjs/operators';

// emit error
const source = throwError('This is an error!');

// gracefully handle error, returning observable with error message
const example = source.pipe(
  catchError(val => of(`I caught: ${val}`))
);

// output: 'I caught: This is an error'
const subscribe = example.subscribe(val => console.log(val));
```

### Example 2: Catching rejected promise

( [StackBlitz](https://stackblitz.com/edit/typescript-nte3xs?file=index.ts\&devtoolsheight=100) )

```js
// RxJS v6+
import { timer, from, of } from 'rxjs';
import { mergeMap, catchError } from 'rxjs/operators';

// create promise that immediately rejects
const myBadPromise = () =>
  new Promise((resolve, reject) => reject('Rejected!'));

// emit single value after 1 second
const source = timer(1000);

// catch rejected promise, returning observable containing error message
const example = source.pipe(
  mergeMap(_ =>
    from(myBadPromise()).pipe(
      catchError(error => of(`Bad Promise: ${error}`))
    )
  )
);

// output: 'Bad Promise: Rejected'
const subscribe = example.subscribe(val => console.log(val));
```

### Example 3: Catching errors comparison when using switchMap/mergeMap/concatMap/exhaustMap

( [StackBlitz](https://stackblitz.com/edit/rxjs-catcherror-withmapoperators?file=index.ts\&devtoolsheight=80) )

```js
// RxJS v6+
import { throwError, fromEvent, of } from 'rxjs';
import {
  catchError,
  tap,
  switchMap,
  mergeMap,
  concatMap,
  exhaustMap
} from 'rxjs/operators';

// simulate an API call that throws an error
const fakeRequest$ = of().pipe(
  tap(_ => console.log('fakeRequest')),
  throwError
);

/*
 * Placement of catchError MATTERS!
 *
 * When catchError is placed INSIDE the switchMap, only the inner
 * observable errors out and the outer stream continues.
 * You can keep clicking and making new requests.
 */
const iWillContinueListening$ = fromEvent(
  document.getElementById('continued'),
  'click'
).pipe(
  switchMap(_ => 
    fakeRequest$.pipe(
      catchError(_ => of('keep on clicking!!!'))
    )
  )
);

/*
 * When catchError is placed at the OUTER level, after switchMap,
 * the entire stream errors out and terminates.
 * After the first click, the stream is dead and won't respond to more clicks.
 */
const iWillStopListening$ = fromEvent(
  document.getElementById('stopped'),
  'click'
).pipe(
  switchMap(_ => fakeRequest$),
  catchError(_ => of('no more requests!!!'))
);

iWillContinueListening$.subscribe(console.log);
iWillStopListening$.subscribe(console.log);
```

### Example 4: Providing fallback data on HTTP error

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

```js
// RxJS v6+
import { ajax } from 'rxjs/ajax';
import { of } from 'rxjs';
import { catchError, map } from 'rxjs/operators';

// attempt to fetch user data from API
const userData$ = ajax.getJSON('https://api.example.com/user/123').pipe(
  map(response => response.data),
  // if the request fails, provide cached or default data
  catchError(error => {
    console.error('Failed to fetch user, using cached data', error);
    return of({ 
      id: 123, 
      name: 'Cached User', 
      status: 'offline' 
    });
  })
);

// user always gets data, even if the API is down
userData$.subscribe(user => console.log('User:', user));
```

***

## Related Recipes

* [Smart Counter](/learn-rxjs/recipes/smartcounter)
* [HTTP Polling](/learn-rxjs/recipes/http-polling)

***

## Additional Resources

* [catchError](https://rxjs.dev/api/operators/catchError) 📰 - Official docs
* [Error handling operator: catch](https://egghead.io/lessons/rxjs-error-handling-operator-catch?course=rxjs-beyond-the-basics-operators-in-depth) 🎥 💵 - André Staltz
* [Error Handling in RxJS](https://blog.angular-university.io/rxjs-error-handling/) 📰 - Angular University

***

📁 **Source Code:** <https://github.com/ReactiveX/rxjs/blob/master/packages/rxjs/src/internal/operators/catchError.ts>


# retry

#### signature: `retry(number: number): Observable`

## Retry an observable sequence a specific number of times should an error occur.

***

💡 Useful for retrying HTTP requests!

💡 If you only want to retry in certain cases, check out [`retryWhen`](/learn-rxjs/operators/error_handling/retrywhen)!

💡 For non error cases check out [`repeat`](/learn-rxjs/operators/utility/repeat)!

***

### Examples

**Example 1: Retry 2 times on error**

( [StackBlitz](https://stackblitz.com/edit/typescript-jpjcpg?file=index.ts\&devtoolsheight=100) | [jsBin](http://jsbin.com/yovacuxuqa/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/hg7z16bo/) )

```js
// RxJS v6+
import { interval, of, throwError } from 'rxjs';
import { mergeMap, retry } from 'rxjs/operators';

//emit value every 1s
const source = interval(1000);
const example = source.pipe(
  mergeMap(val => {
    //throw error for demonstration
    if (val > 5) {
      return throwError('Error!');
    }
    return of(val);
  }),
  //retry 2 times on error
  retry(2)
);
/*
  output:
  0..1..2..3..4..5..
  0..1..2..3..4..5..
  0..1..2..3..4..5..
  "Error!: Retried 2 times then quit!"
*/
const subscribe = example.subscribe({
  next: val => console.log(val),
  error: val => console.log(`${val}: Retried 2 times then quit!`)
});
```

### Additional Resources

* [retry](https://rxjs.dev/api/operators/retry) 📰 - Official docs
* [Error handling operator: retry and retryWhen](https://egghead.io/lessons/rxjs-error-handling-operator-retry-and-retrywhen?course=rxjs-beyond-the-basics-operators-in-depth) 🎥 💵 - André Staltz

***

> 📁 Source Code: <https://github.com/ReactiveX/rxjs/blob/master/packages/rxjs/src/internal/operators/retry.ts>


# retryWhen

#### signature: `retryWhen(receives: (errors: Observable) => Observable, the: scheduler): Observable`

## Retry an observable sequence on error based on custom criteria.

### Examples

**Example 1: Trigger retry after specified duration**

( [StackBlitz](https://stackblitz.com/edit/typescript-zpbsw6?file=index.ts\&devtoolsheight=100) | [jsBin](http://jsbin.com/miduqexalo/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/49mkhsyr/) )

```js
// RxJS v6+
import { timer, interval } from 'rxjs';
import { map, tap, retryWhen, delayWhen } from 'rxjs/operators';

//emit value every 1s
const source = interval(1000);
const example = source.pipe(
  map(val => {
    if (val > 5) {
      //error will be picked up by retryWhen
      throw val;
    }
    return val;
  }),
  retryWhen(errors =>
    errors.pipe(
      //log error message
      tap(val => console.log(`Value ${val} was too high!`)),
      //restart in 6 seconds
      delayWhen(val => timer(val * 1000))
    )
  )
);
/*
  output:
  0
  1
  2
  3
  4
  5
  "Value 6 was too high!"
  --Wait 6 seconds then repeat
*/
const subscribe = example.subscribe(val => console.log(val));
```

**Example 2: Customizable retry with increased duration**

( [StackBlitz](https://stackblitz.com/edit/angular-cwnknr?file=app%2Frxjs-utils.ts) )

```js
import { Observable, throwError, timer } from 'rxjs';
import { mergeMap, finalize } from 'rxjs/operators';

export const genericRetryStrategy = ({
  maxRetryAttempts = 3,
  scalingDuration = 1000,
  excludedStatusCodes = []
}: {
  maxRetryAttempts?: number,
  scalingDuration?: number,
  excludedStatusCodes?: number[]
} = {}) => (attempts: Observable<any>) => {
  return attempts.pipe(
    mergeMap((error, i) => {
      const retryAttempt = i + 1;
      // if maximum number of retries have been met
      // or response is a status code we don't wish to retry, throw error
      if (
        retryAttempt > maxRetryAttempts ||
        excludedStatusCodes.find(e => e === error.status)
      ) {
        return throwError(error);
      }
      console.log(
        `Attempt ${retryAttempt}: retrying in ${retryAttempt *
          scalingDuration}ms`
      );
      // retry after 1s, 2s, etc...
      return timer(retryAttempt * scalingDuration);
    }),
    finalize(() => console.log('We are done!'))
  );
};
```

```js
import { Component, OnInit } from '@angular/core';
import { catchError, retryWhen  } from 'rxjs/operators';
import { of } from 'rxjs';
import { genericRetryStrategy } from './rxjs-utils';
import { AppService } from './app.service';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent implements OnInit  {
  constructor(private _appService: AppService) {}

  ngOnInit() {
    this._appService
      .getData(500)
      .pipe(
        retryWhen(genericRetryStrategy()),
        catchError(error => of(error))
      )
      .subscribe(console.log);

    // excluding status code, delay for logging clarity
    setTimeout(() => {
    this._appService
      .getData(500)
      .pipe(
        retryWhen(genericRetryStrategy({
          scalingDuration: 2000,
          excludedStatusCodes: [500]
        })),
        catchError(error => of(error))
      )
      .subscribe(e => console.log('Exluded code:', e.status));

    }, 8000);
  }
}
```

### Additional Resources

* [retryWhen](https://rxjs.dev/api/operators/retryWhen) 📰 - Official docs
* [Error handling operator: retry and retryWhen](https://egghead.io/lessons/rxjs-error-handling-operator-retry-and-retrywhen?course=rxjs-beyond-the-basics-operators-in-depth) 🎥 💵 - André Staltz

***

> 📁 Source Code: <https://github.com/ReactiveX/rxjs/blob/master/packages/rxjs/src/internal/operators/retryWhen.ts>


# Multicasting

In RxJS observables are cold, or unicast by default. These operators can make an observable hot, or multicast, allowing side-effects to be shared among multiple subscribers.

## Contents

* [publish](/learn-rxjs/operators/multicasting/publish)
* [multicast](/learn-rxjs/operators/multicasting/multicast)
* [share](/learn-rxjs/operators/multicasting/share) ⭐
* [shareReplay](/learn-rxjs/operators/multicasting/sharereplay) ⭐

⭐ - *commonly used*

### Additional Resources

* [Hot vs Cold Observables](https://medium.com/@benlesh/hot-vs-cold-observables-f8094ed53339#.8x9uam5rg) 📰 - Ben Lesh
* [Unicast v Multicast](https://github.com/zenparsing/es-observable/issues/66) 📰 - GitHub Discussion
* [Demystifying Hot and Cold Observables](https://egghead.io/lessons/rxjs-demystifying-cold-and-hot-observables-in-rxjs) 🎥 - André Staltz


# publish

#### signature: `publish() : ConnectableObservable`

## Share source and make hot by calling connect.

### Examples

**Example 1: Connect observable after subscribers**

( [StackBlitz](https://stackblitz.com/edit/typescript-zje8ms?file=index.ts\&devtoolsheight=100) | [jsBin](http://jsbin.com/laguvecixi/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/fpe6csaz/) )

```js
// RxJS v6+
import { interval } from 'rxjs';
import { publish, tap } from 'rxjs/operators';

//emit value every 1 second
const source = interval(1000);
//do nothing until connect() is called
const example = publish()(source.pipe(
  //side effects will be executed once
  tap(_ => console.log('Do Something!')),
));

/*
  source will not emit values until connect() is called
  output: (after 5s)
  "Do Something!"
  "Subscriber One: 0"
  "Subscriber Two: 0"
  "Do Something!"
  "Subscriber One: 1"
  "Subscriber Two: 1"
*/
const subscribe = example.subscribe(val =>
  console.log(`Subscriber One: ${val}`)
);
const subscribeTwo = example.subscribe(val =>
  console.log(`Subscriber Two: ${val}`)
);

//call connect after 5 seconds, causing source to begin emitting items
setTimeout(() => {
  example.connect();
}, 5000);

```

### Additional Resources

* [publish](https://rxjs.dev/api/operators/publish) 📰 - Official docs

> 📁 Source Code: <https://github.com/ReactiveX/rxjs/blob/master/packages/rxjs/src/internal/operators/publish.ts>


# multicast

#### signature: `multicast(selector: Function): Observable`

## Share source utilizing the provided Subject.

### Examples

**Example 1: multicast with standard Subject**

( [StackBlitz](https://stackblitz.com/edit/typescript-vge8sk?file=index.ts\&devtoolsheight=100) | [jsBin](http://jsbin.com/zexuyosuvi/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/x2z7p1gm/) )

```js
// RxJS v6+
import { Subject, interval } from 'rxjs';
import { take, tap, multicast, mapTo } from 'rxjs/operators';

//emit every 2 seconds, take 5
const source = interval(2000).pipe(take(5));

const example = source.pipe(
  //since we are multicasting below, side effects will be executed once
  tap(() => console.log('Side Effect #1')),
  mapTo('Result!')
);

//subscribe subject to source upon connect()
const multi = example.pipe(multicast(() => new Subject()));
/*
  subscribers will share source
  output:
  "Side Effect #1"
  "Result!"
  "Result!"
  ...
*/
const subscriberOne = multi.subscribe(val => console.log(val));
const subscriberTwo = multi.subscribe(val => console.log(val));
//subscribe subject to source
multi.connect();
```

**Example 2: multicast with ReplaySubject**

( [StackBlitz](https://stackblitz.com/edit/typescript-n5ghjj?file=index.ts\&devtoolsheight=100) | [jsBin](http://jsbin.com/ruhexuhike/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/oj68u58j/) )

```js
// RxJS v6+
import { interval, ReplaySubject } from 'rxjs';
import { take, multicast, tap, mapTo } from 'rxjs/operators';

//emit every 2 seconds, take 5
const source = interval(2000).pipe(take(5));

//example with ReplaySubject
const example = source.pipe(
  //since we are multicasting below, side effects will be executed once
  tap(_ => console.log('Side Effect #2')),
  mapTo('Result Two!')
);
//can use any type of subject
const multi = example.pipe(multicast(() => new ReplaySubject(5)));
//subscribe subject to source
multi.connect();

setTimeout(() => {
  /*
   subscriber will receieve all previous values on subscription because
   of ReplaySubject
   */
  const subscriber = multi.subscribe(val => console.group(val));
}, 5000);
```

### Additional Resources

* [multicast](https://rxjs.dev/api/operators/multicast) 📰 - Official docs

***

> 📁 Source Code: <https://github.com/ReactiveX/rxjs/blob/master/packages/rxjs/src/internal/operators/multicast.ts>


# share

#### signature: `share(): Observable`

## Share source among multiple subscribers.

***

💡 share is like [multicast](/learn-rxjs/operators/multicasting/multicast) with a Subject and refCount!

***

### Examples

**Example 1: Multiple subscribers sharing source**

( [StackBlitz](https://stackblitz.com/edit/typescript-dlaa1p?file=index.ts\&devtoolsheight=100) | [jsBin](http://jsbin.com/jobiyomari/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/Lmesxxaq/) )

```js
// RxJS v6+
import { timer } from 'rxjs';
import { tap, mapTo, share } from 'rxjs/operators';

//emit value in 1s
const source = timer(1000);
//log side effect, emit result
const example = source.pipe(
  tap(() => console.log('***SIDE EFFECT***')),
  mapTo('***RESULT***')
);

/*
  ***NOT SHARED, SIDE EFFECT WILL BE EXECUTED TWICE***
  output:
  "***SIDE EFFECT***"
  "***RESULT***"
  "***SIDE EFFECT***"
  "***RESULT***"
*/
const subscribe = example.subscribe(val => console.log(val));
const subscribeTwo = example.subscribe(val => console.log(val));

//share observable among subscribers
const sharedExample = example.pipe(share());
/*
  ***SHARED, SIDE EFFECT EXECUTED ONCE***
  output:
  "***SIDE EFFECT***"
  "***RESULT***"
  "***RESULT***"
*/
const subscribeThree = sharedExample.subscribe(val => console.log(val));
const subscribeFour = sharedExample.subscribe(val => console.log(val));
```

### Related Recipes

* [Progress Bar](/learn-rxjs/recipes/progressbar)
* [Game Loop](/learn-rxjs/recipes/gameloop)
* [Save Indicator](/learn-rxjs/recipes/save-indicator)

### Additional Resources

* [share](https://rxjs.dev/api/operators/share) 📰 - Official docs
* [Sharing streams with share](https://egghead.io/lessons/rxjs-sharing-streams-with-share?course=step-by-step-async-javascript-with-rxjs) 🎥 💵 - John Linquist

***

> 📁 Source Code: <https://github.com/ReactiveX/rxjs/blob/master/packages/rxjs/src/internal/operators/share.ts>


# shareReplay

#### signature: `shareReplay(bufferSize?: number, windowTime?: number, scheduler?I IScheduler): Observable`

## Share source and replay specified number of emissions on subscription.

### Why use `shareReplay`?

You generally want to use `shareReplay` when you have side-effects or taxing computations that you do not wish to be executed amongst multiple subscribers. It may also be valuable in situations where you know you will have late subscribers to a stream that need access to previously emitted values. This ability to *replay* values on subscription is what differentiates [`share`](/learn-rxjs/operators/multicasting/share) and `shareReplay`.

For instance, suppose you have an observable that emits the last visited url. In the first example we are going to use [`share`](/learn-rxjs/operators/multicasting/share):

```js
// simulate url change with subject
const routeEnd = new Subject<{data: any, url: string}>();

// grab url and share with subscribers
const lastUrl = routeEnd.pipe(
  pluck('url'),
  share()
);

// initial subscriber required
const initialSubscriber = lastUrl.subscribe(console.log);

// simulate route change
routeEnd.next({data: {}, url: 'my-path'});

// nothing logged
const lateSubscriber = lastUrl.subscribe(console.log);
```

In the above example nothing is logged as the `lateSubscriber` subscribes to the source. Now suppose instead we wanted to give access to the last emitted value on subscription, we can accomplish this with `shareReplay`:

```js
import { Subject } from 'rxjs/Subject';
import { ReplaySubject } from 'rxjs/ReplaySubject';
import { pluck, share, shareReplay, tap } from 'rxjs/operators';

// simulate url change with subject
const routeEnd = new Subject<{data: any, url: string}>();

// grab url and share with subscribers
const lastUrl = routeEnd.pipe(
  tap(_ => console.log('executed')),
  pluck('url'),
  // defaults to all values so we set it to just keep and replay last one
  shareReplay(1)
);

// requires initial subscription
const initialSubscriber = lastUrl.subscribe(console.log);

// simulate route change
// logged: 'executed', 'my-path'
routeEnd.next({data: {}, url: 'my-path'});

// logged: 'my-path'
const lateSubscriber = lastUrl.subscribe(console.log);
```

Note that this is similar behavior to what you would see if you subscribed a `ReplaySubject` to the `lastUrl` stream, then subscribed to that `Subject`:

```js
// simulate url change with subject
const routeEnd = new Subject<{data: any, url: string}>();

// instead of using shareReplay, use ReplaySubject
const shareWithReplay = new ReplaySubject();

// grab url and share with subscribers
const lastUrl = routeEnd.pipe(
  pluck('url')
)
.subscribe(val => shareWithReplay.next(val));

// simulate route change
routeEnd.next({data: {}, url: 'my-path'});

// subscribe to ReplaySubject instead
// logged: 'my path'
shareWithReplay.subscribe(console.log);
```

In fact, if we dig into the source code we can see a very similar technique is being used. When a subscription is made, `shareReplay` will subscribe to the source, sending values through an internal `ReplaySubject`:

( [source](https://github.com/ReactiveX/rxjs/blob/b25db9f369b07f26cf2fc11714ec1990b78a4536/packages/rxjs/src/internal/operators/shareReplay.ts#L26-L37) )

```js
  return function shareReplayOperation(this: Subscriber<T>, source: Observable<T>) {
    refCount++;
    if (!subject || hasError) {
      hasError = false;
      subject = new ReplaySubject<T>(bufferSize, windowTime, scheduler);
      subscription = source.subscribe({
        next(value) { subject.next(value); },
        error(err) {
          hasError = true;
          subject.error(err);
        },
        complete() {
          isComplete = true;
          subject.complete();
        },
      });
    }


    const innerSub = subject.subscribe(this);


    return () => {
      refCount--;
      innerSub.unsubscribe();
      if (subscription && refCount === 0 && isComplete) {
        subscription.unsubscribe();
      }
    };
  };
}
```

### Examples

**Example 1: Multiple subscribers sharing source**

( [Stackblitz](https://stackblitz.com/edit/typescript-9cfnxm?file=index.ts\&devtoolsheight=100) )

```js
// RxJS v6+
import { Subject, ReplaySubject } from 'rxjs';
import { pluck, share, shareReplay, tap } from 'rxjs/operators';

// simulate url change with subject
const routeEnd = new Subject<{data: any, url: string}>();
// grab url and share with subscribers
const lastUrl = routeEnd.pipe(
  tap(_ => console.log('executed')),
  pluck('url'),
  // defaults to all values so we set it to just keep and replay last one
  shareReplay(1)
);
// requires initial subscription
const initialSubscriber = lastUrl.subscribe(console.log)
// simulate route change
// logged: 'executed', 'my-path'
routeEnd.next({data: {}, url: 'my-path'});
// logged: 'my-path'
const lateSubscriber = lastUrl.subscribe(console.log);
```

### Additional Resources

* [shareReplay](https://rxjs.dev/api/operators/shareReplay) 📰 - Official docs

***

> 📁 Source Code: <https://github.com/ReactiveX/rxjs/blob/master/packages/rxjs/src/internal/operators/shareReplay.ts>


# Filtering

In a [push based approach](http://reactivex.io/rxjs/manual/overview.html#pull-versus-push), picking and choosing how and when to accept items is important. These operators provide techniques for accepting values from an observable source and dealing with [backpressure](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/gettingstarted/backpressure.md).

## Contents

* [audit](/learn-rxjs/operators/filtering/audit)
* [auditTime](/learn-rxjs/operators/filtering/audittime)
* [debounce](/learn-rxjs/operators/filtering/debounce)
* [debounceTime](/learn-rxjs/operators/filtering/debouncetime) ⭐
* [distinct](/learn-rxjs/operators/filtering/distinct)
* [distinctUntilChanged](/learn-rxjs/operators/filtering/distinctuntilchanged) ⭐
* [distinctUntilKeyChanged](/learn-rxjs/operators/filtering/distinctuntilkeychanged)
* [filter](/learn-rxjs/operators/filtering/filter) ⭐
* [find](/learn-rxjs/operators/filtering/find)
* [first](/learn-rxjs/operators/filtering/first)
* [ignoreElements](/learn-rxjs/operators/filtering/ignoreelements)
* [last](/learn-rxjs/operators/filtering/last)
* [sample](/learn-rxjs/operators/filtering/sample)
* [single](/learn-rxjs/operators/filtering/single)
* [skip](/learn-rxjs/operators/filtering/skip)
* [skipUntil](/learn-rxjs/operators/filtering/skipuntil)
* [skipWhile](/learn-rxjs/operators/filtering/skipwhile)
* [take](/learn-rxjs/operators/filtering/take) ⭐
* [takeLast](/learn-rxjs/operators/filtering/takelast)
* [takeUntil](/learn-rxjs/operators/filtering/takeuntil) ⭐
* [takeWhile](/learn-rxjs/operators/filtering/takewhile)
* [throttle](/learn-rxjs/operators/filtering/throttle)
* [throttleTime](/learn-rxjs/operators/filtering/throttletime)

⭐ - *commonly used*


# audit

#### signature: `audit(durationSelector: (value) => Observable | Promise): Observable`

## Ignore for time based on provided observable, then emit most recent value

### \[ Examples Coming Soon! ]

### Additional Resources

* [audit](https://rxjs.dev/api/operators/audit) 📰 - Official docs

***

> 📁 Source Code: <https://github.com/ReactiveX/rxjs/blob/master/packages/rxjs/src/internal/operators/audit.ts>


# auditTime

#### signature: `auditTime(duration: number, scheduler?: Scheduler): Observable`

## Ignore for given time then emit most recent value

### Why use `auditTime`

When you are interested in ignoring a source observable for a given amount of time, you can use `auditTime`. A possible use case is to only emit certain events (i.e. mouse clicks) at a maximum rate per second. After the specified duration has passed, the timer is disabled and the most recent source value is emitted on the output Observable, and this process repeats for the next source value.

***

💡 If you want the timer to reset whenever a new event occurs on the source observable, you can use [debounceTime](/learn-rxjs/operators/filtering/debouncetime)

***

### Examples

**Example 1: Emit clicks at a rate of at most one click per second**

( [stackBlitz](https://stackblitz.com/edit/typescript-skykxw) )

```js
import { fromEvent } from 'rxjs';
import { auditTime } from 'rxjs/operators';

// Create observable that emits click events
const source = fromEvent(document, 'click');
// Emit clicks at a rate of at most one click per second
const example = source.pipe(auditTime(1000))
// Output (example): '(1s) --- Clicked --- (1s) --- Clicked' 
const subscribe = example.subscribe(val => console.log('Clicked'));
```

### Additional Resources

* [auditTime](https://rxjs.dev/api/operators/auditTime) 📰 - Official docs
* [Time based operators comparison](/learn-rxjs/concepts/time-based-operators-comparison)

***

> 📁 Source Code: <https://github.com/ReactiveX/rxjs/blob/master/packages/rxjs/src/internal/operators/auditTime.ts>


# debounce

#### signature: `debounce(durationSelector: function): Observable`

## Discard emitted values that take less than the specified time, based on selector function, between output.

***

💡 Though not as widely used as [debounceTime](/learn-rxjs/operators/filtering/debouncetime), **debounce** is important when the debounce rate is variable!

***

### Examples

**Example 1: Debounce on timer**

( [StackBlitz](https://stackblitz.com/edit/typescript-dzjbra?file=index.ts\&devtoolsheight=100) | [jsBin](http://jsbin.com/sorimeyoro/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/e5698yow/) )

```js
// RxJS v6+
import { of, timer } from 'rxjs';
import { debounce } from 'rxjs/operators';

//emit four strings
const example = of('WAIT', 'ONE', 'SECOND', 'Last will display');
/*
    Only emit values after a second has passed between the last emission,
    throw away all other values
*/
const debouncedExample = example.pipe(debounce(() => timer(1000)));
/*
    In this example, all values but the last will be omitted
    output: 'Last will display'
*/
const subscribe = debouncedExample.subscribe(val => console.log(val));
```

**Example 2: Debounce at increasing interval**

( [StackBlitz](https://stackblitz.com/edit/typescript-qnfidr?file=index.ts\&devtoolsheight=100) | [jsBin](http://jsbin.com/sotaretese/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/6ab34nq6/) )

```js
// RxJS v6+
import { interval, timer } from 'rxjs';
import { debounce } from 'rxjs/operators';

//emit value every 1 second, ex. 0...1...2
const interval$ = interval(1000);
//raise the debounce time by 200ms each second
const debouncedInterval = interval$.pipe(debounce(val => timer(val * 200)));
/*
  After 5 seconds, debounce time will be greater than interval time,
  all future values will be thrown away
  output: 0...1...2...3...4......(debounce time over 1s, no values emitted)
*/
const subscribe = debouncedInterval.subscribe(val =>
  console.log(`Example Two: ${val}`)
);
```

### Additional Resources

* [debounce](https://rxjs.dev/api/operators/debounce) 📰 - Official docs
* [Transformation operator: debounce and debounceTime](https://egghead.io/lessons/rxjs-transformation-operators-debounce-and-debouncetime?course=rxjs-beyond-the-basics-operators-in-depth) 🎥 💵 - André Staltz

***

> 📁 Source Code: <https://github.com/ReactiveX/rxjs/blob/master/packages/rxjs/src/internal/operators/debounce.ts>


# debounceTime

#### signature: `debounceTime(dueTime: number, scheduler: Scheduler): Observable`

## Discard emitted values that take less than the specified time between output

***

💡 This operator is popular in scenarios such as type-ahead where the rate of user input must be controlled!

***

### Why use `debounceTime`?

Think of `debounceTime` like taking a pause in a conversation to let the other person finish their thought. This operator is incredibly handy when you're dealing with rapid sequences of events and only care about acting upon the last event after a specified duration.

A classic real-world application is in form inputs, particularly in search bars. Imagine you're typing into a search box. Instead of firing off an API call with every keystroke (which can be overwhelming and inefficient), you'd want to wait a bit after the user stops typing to ensure you're fetching data based on their complete thought. That "waiting a bit" is where `debounceTime` shines. For instance, by setting `debounceTime(300)`, the system will wait for 300 milliseconds after the last keystroke before it proceeds.

In Angular, when dealing with reactive forms, `debounceTime` is a lifesaver. By adding this operator to a form control's value changes observable, you can efficiently handle values only after users finish their input. Check out the below example:

```typescript
this.myFormControl.valueChanges.pipe(
  debounceTime(300)
).subscribe(value => {
  // handle the value after 300ms of inactivity
});
```

### Examples

**Example 1: Debouncing based on time between input**

( [StackBlitz](https://stackblitz.com/edit/typescript-adheqt?file=index.ts\&devtoolsheight=50) )

```js
// RxJS v6+
import { fromEvent } from 'rxjs';
import { debounceTime, map } from 'rxjs/operators';

// elem ref
const searchBox = document.getElementById('search');

// streams
const keyup$ = fromEvent(searchBox, 'keyup');

// wait .5s between keyups to emit current value
keyup$
  .pipe(
    map((i: any) => i.currentTarget.value),
    debounceTime(500)
  )
  .subscribe(console.log);
```

### Related Recipes

* [Save Indicator](/learn-rxjs/recipes/save-indicator)
* [Type Ahead](/learn-rxjs/recipes/type-ahead)

### Additional Resources

* [debounceTime](https://rxjs.dev/api/operators/debounceTime) 📰 - Official docs
* [Transformation operator: debounce and debounceTime](https://egghead.io/lessons/rxjs-transformation-operators-debounce-and-debouncetime?course=rxjs-beyond-the-basics-operators-in-depth) 🎥 💵 - André Staltz
* [Time based operators comparison](/learn-rxjs/concepts/time-based-operators-comparison)

***

> 📁 Source Code: <https://github.com/ReactiveX/rxjs/blob/master/packages/rxjs/src/internal/operators/debounceTime.ts>


# distinct

#### signature: `distinct(keySelector?, flushes?): Observable`

## Emits items emitted that are distinct based on any previously emitted item.

### Examples

**Example 1: distinct without selector**

( [StackBlitz](https://stackblitz.com/edit/rxjs-distinct-example-wphfch?file=index.ts\&devtoolsheight=100) )

```js
// RxJS v6+
import { of } from 'rxjs';
import { distinct } from 'rxjs/operators';

of(1, 2, 3, 4, 5, 1, 2, 3, 4, 5)
  .pipe(distinct())
  // OUTPUT: 1,2,3,4,5
  .subscribe(console.log);
```

**Example 2: distinct with key selector**

( [StackBlitz](https://stackblitz.com/edit/rxjs-distinct-example?file=index.ts\&devtoolsheight=100) )

```js
// RxJS v6+
import { from } from 'rxjs';
import { distinct } from 'rxjs/operators';

const obj1 = { id: 3, name: 'name 1' };
const obj2 = { id: 4, name: 'name 2' };
const obj3 = { id: 3, name: 'name 3' };
const vals = [obj1, obj2, obj3];

from(vals)
  .pipe(distinct(e => e.id))
  .subscribe(console.log);

/*
OUTPUT:
{id: 3, name: "name 1"}
{id: 4, name: "name 2"}
 */
```

### Additional Resources

* [distinct](https://rxjs.dev/api/operators/distinct) 📰 - Official docs

***

> 📁 Source Code: <https://github.com/ReactiveX/rxjs/blob/master/packages/rxjs/src/internal/operators/distinct.ts>


# distinctUntilChanged

#### signature: `distinctUntilChanged(compare: function): Observable`

## Only emit when the current value is different than the last.

***

💡 distinctUntilChanged uses `===` comparison by default, object references must match!

💡 If you want to compare based on an object property, you can use [`distinctUntilKeyChanged`](/learn-rxjs/operators/filtering/distinctuntilkeychanged) instead!

***

### Why use `distinctUntilChanged`?

This operator stands guard, ensuring that you're not bombarded with repetitive information. Imagine if your best friend kept repeating the same story to you every time you met. It'd get old, right? The `distinctUntilChanged` operator does just that; it prevents subsequent identical emissions from an observable.

Think about a search bar on a website. As users type their queries, you don't want to send a server request for the same input value multiple times in a row, it would be redundant and inefficient. Here’s where `distinctUntilChanged` combined with [`debounceTime`](/learn-rxjs/operators/filtering/debouncetime) could shine. Imagine a user typing in a search term and then slightly hesitating before adding another letter. You might want to wait just a little bit (that’s (`debounceTime`)\[debouncetime.md] doing its magic) and then, before firing off a request, ensure the term is actually different than the previous one - this is where you can utilize `distinctUntilChanged`.

For example, if a user is searching for "apple" and they type "app" -> wait a bit -> "appl" -> backtrack to "app" -> type again "appl", without `distinctUntilChanged`, you might end up sending redundant requests. But with it, once "appl" is recognized as previously processed, it won't send the redundant search request again.

It's important to remember that **`distinctUntilChanged` compares the current value with the last emitted value**. It doesn’t keep a long history. So, if an observable emitted the values 1, 2, 2, 3, 3, 2 - you’d get 1, 2, 3, 2 in return. By default, it also uses simple equality to compare values. If you're working with objects or arrays, you might need to provide a custom comparison function to determine whether values are distinct.

In essence, when you're looking to filter out consecutive duplicate emissions from your observables, think of `distinctUntilChanged` as your go-to option.

### Examples

**Example 1: distinctUntilChanged with basic values**

( [StackBlitz](https://stackblitz.com/edit/typescript-bsb8mw?file=index.ts\&devtoolsheight=100) )

```js
// RxJS v6+
import { from } from 'rxjs';
import { distinctUntilChanged } from 'rxjs/operators';

// only output distinct values, based on the last emitted value
const source$ = from([1, 1, 2, 2, 3, 3]);

source$
  .pipe(distinctUntilChanged())
  // output: 1,2,3
  .subscribe(console.log);
```

**Example 2: distinctUntilChanged with objects**

( [StackBlitz](https://stackblitz.com/edit/typescript-moe7mh?file=index.ts\&devtoolsheight=100) )

```js
// RxJS v6+
import { from } from 'rxjs';
import { distinctUntilChanged } from 'rxjs/operators';

const sampleObject = { name: 'Test' };

//Objects must be same reference
const source$ = from([sampleObject, sampleObject, sampleObject]);

// only emit distinct objects, based on last emitted value
source$
  .pipe(distinctUntilChanged())
  // output: {name: 'Test'}
  .subscribe(console.log);
```

**Example 3: Using custom comparer function**

( [StackBlitz](https://stackblitz.com/edit/typescript-hzta27?file=index.ts\&devtoolsheight=100) )

```js
// RxJS v6+
import { from } from 'rxjs';
import { distinctUntilChanged } from 'rxjs/operators';

// only output distinct values, based on the last emitted value
const source$ = from([
  { name: 'Brian' },
  { name: 'Joe' },
  { name: 'Joe' },
  { name: 'Sue' }
]);

source$
  // custom compare for name
  .pipe(distinctUntilChanged((prev, curr) => prev.name === curr.name))
  // output: { name: 'Brian }, { name: 'Joe' }, { name: 'Sue' }
  .subscribe(console.log);
```

### Related Recipes

* [Lockscreen](/learn-rxjs/recipes/lockscreen)
* [Save Indicator](/learn-rxjs/recipes/save-indicator)
* [Type Ahead](/learn-rxjs/recipes/type-ahead)

### Additional Resources

* [distinctUntilChanged](https://rxjs.dev/api/operators/distinctUntilChanged) 📰 - Official docs
* [Filtering operator: distinct and distinctUntilChanged](https://egghead.io/lessons/rxjs-filtering-operators-distinct-and-distinctuntilchanged?course=rxjs-beyond-the-basics-operators-in-depth) 🎥 💵 - André Staltz

***

> 📁 Source Code: <https://github.com/ReactiveX/rxjs/blob/master/packages/rxjs/src/internal/operators/distinctUntilChanged.ts>


# distinctUntilKeyChanged

#### signature: `distinctUntilKeyChanged(key, compare?: fn): Observable`

## Only emit when the specified key value changes

💡 If you're comparing entire values, use [distinctUntilChanged](/learn-rxjs/operators/filtering/distinctuntilchanged) instead!\
💡 For truly unique values across the entire stream (not just consecutive), check out [distinct](/learn-rxjs/operators/filtering/distinct)!

### Why use distinctUntilKeyChanged?

When you're working with streams of objects—think user profiles, product items, or API responses, you often care about changes to a specific property rather than the entire object. Maybe you're tracking users by their ID, filtering products by SKU, or monitoring status updates. That's where `distinctUntilKeyChanged` shines.

Think of it like having a smart doorman at a club who recognizes people by their membership cards. Even if someone changes their outfit or hairstyle (other object properties), the doorman only cares about the card number. If you try to enter twice in a row with the same card, they'll stop you the second time: "You're already inside!" But if someone else with a different card shows up, they're let through. That's exactly what `distinctUntilKeyChanged` does—it checks a specific "card" (key) on each object and only lets through consecutive duplicates.

This is incredibly useful for scenarios like live data feeds where objects might be re-emitted frequently but you only want to react when a specific property actually changes. For instance, you might receive user objects from a WebSocket connection, but you only want to update your UI when the user's status field changes from 'online' to 'offline', not every time the object is re-broadcast. By using `distinctUntilKeyChanged('status')`, you filter out the noise and [react only to meaningful changes](#example-1-compare-based-on-key).

### Examples

**Example 1: Compare based on key**

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

```js
// RxJS v6+
import { from } from 'rxjs';
import { distinctUntilKeyChanged } from 'rxjs/operators';

// only output distinct values based on the 'name' key
const source$ = from([
  { name: 'Brian' },
  { name: 'Joe' },
  { name: 'Joe' },
  { name: 'Sue' }
]);

source$
  // only emit when name property changes
  .pipe(distinctUntilKeyChanged('name'))
  // output: { name: 'Brian' }, { name: 'Joe' }, { name: 'Sue' }
  .subscribe(console.log);
```

**Example 2: Keyboard events**

( [StackBlitz](https://stackblitz.com/edit/rxjs-distinctuntilkeychanged?file=index.ts\&devtoolsheight=50) )

```js
// RxJS v6+
import { fromEvent } from 'rxjs';
import { distinctUntilKeyChanged, map } from 'rxjs/operators';

// listen to keyboard events
const keys$ = fromEvent(document, 'keyup').pipe(
  // only emit when the 'code' property changes (ignore repeated key holds)
  distinctUntilKeyChanged<KeyboardEvent>('code'),
  // extract the actual key value for display
  map(e => e?.key)
);

keys$.subscribe(console.log);
```

**Example 3: Custom comparison function**

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

```js
// RxJS v6+
import { of } from 'rxjs';
import { distinctUntilKeyChanged } from 'rxjs/operators';

interface Person {
  age: number;
  name: string;
}

// stream of person objects
const people$ = of<Person>(
  { age: 4, name: 'Foo1' },
  { age: 7, name: 'Bar' },
  { age: 5, name: 'Foo2' },
  { age: 6, name: 'Foo3' }
);

people$
  .pipe(
    // only emit when first 3 letters of name change
    distinctUntilKeyChanged(
      'name',
      (x: string, y: string) => x.substring(0, 3) === y.substring(0, 3)
    )
  )
  // output: { age: 4, name: 'Foo1' }, { age: 7, name: 'Bar' }, { age: 5, name: 'Foo2' }
  .subscribe(console.log);
```

### Related Recipes

* [Alphabet Invasion Game](/learn-rxjs/recipes/alphabet-invasion-game)
* [Battleship Game](/learn-rxjs/recipes/battleship-game)

### Additional Resources

* [distinctUntilKeyChanged](https://rxjs.dev/api/operators/distinctUntilKeyChanged) 📰 - Official docs
* [Filtering operator: distinct, distinctUntilChanged, distinctUntilKeyChanged](https://egghead.io/lessons/rxjs-filtering-operators-distinct-distinctuntilchanged-distinctuntilkeychanged) 🎥 - Egghead.io

***

> 📁 Source Code: <https://github.com/ReactiveX/rxjs/blob/master/packages/rxjs/src/internal/operators/distinctUntilKeyChanged.ts>


# filter

#### signature: `filter(select: Function, thisArg: any): Observable`

## Emit values that pass the provided condition.

***

💡 If you would like to complete an observable when a condition fails, check out [takeWhile](/learn-rxjs/operators/filtering/takewhile)!

***

### Why use `filter`?

This operator is your go-to when you need to sift out unwanted values from an observable stream. Think of it as a fisherman's net, catching only the types of fish you desire while allowing others to slip through.

**The critical point to remember** is that `filter` will only emit values that meet the specified condition. If no values in the observable satisfy the condition, nothing gets emitted. It's a strict bouncer at a club's entrance, only letting in those who fit the criteria.

Also, for scenarios where you not only want to filter values but also transform them, [`map`](/learn-rxjs/operators/transformation/map) is an ideal companion to `filter`. Use them in tandem to both shape and refine your data streams.

### Examples

**Example 1: filter for even numbers**

( [StackBlitz](https://stackblitz.com/edit/typescript-4g4cys?file=index.ts\&devtoolsheight=100) | [jsBin](http://jsbin.com/vafogoluye/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/tkz0fuy2/) )

```js
// RxJS v6+
import { from } from 'rxjs';
import { filter } from 'rxjs/operators';

//emit (1,2,3,4,5)
const source = from([1, 2, 3, 4, 5]);
//filter out non-even numbers
const example = source.pipe(filter(num => num % 2 === 0));
//output: "Even number: 2", "Even number: 4"
const subscribe = example.subscribe(val => console.log(`Even number: ${val}`));
```

**Example 2: filter objects based on property**

( [StackBlitz](https://stackblitz.com/edit/typescript-n73fsn?file=index.ts\&devtoolsheight=100) | [jsBin](http://jsbin.com/qihagaxuso/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/yjdsoug1/) )

```js
// RxJS v6+
import { from } from 'rxjs';
import { filter } from 'rxjs/operators';

//emit ({name: 'Joe', age: 31}, {name: 'Bob', age:25})
const source = from([
  { name: 'Joe', age: 31 },
  { name: 'Bob', age: 25 }
]);
//filter out people with age under 30
const example = source.pipe(filter(person => person.age >= 30));
//output: "Over 30: Joe"
const subscribe = example.subscribe(val => console.log(`Over 30: ${val.name}`));
```

**Example 3: filter for number greater than specified value**

( [StackBlitz](https://stackblitz.com/edit/typescript-eyvvfu?file=index.ts\&devtoolsheight=100) | [jsBin](http://jsbin.com/rakabaheyu/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/g1tgreha/) )

```js
// RxJS v6+
import { interval } from 'rxjs';
import { filter } from 'rxjs/operators';

//emit every second
const source = interval(1000);
//filter out all values until interval is greater than 5
const example = source.pipe(filter(num => num > 5));
/*
  "Number greater than 5: 6"
  "Number greater than 5: 7"
  "Number greater than 5: 8"
  "Number greater than 5: 9"
*/
const subscribe = example.subscribe(val =>
  console.log(`Number greater than 5: ${val}`)
);
```

### Related Recipes

* [Battleship Game](/learn-rxjs/recipes/battleship-game)
* [HTTP Polling](/learn-rxjs/recipes/http-polling)
* [Game Loop](/learn-rxjs/recipes/gameloop)
* [Lockscreen](/learn-rxjs/recipes/lockscreen)
* [Mine Sweeper Game](/learn-rxjs/recipes/mine-sweeper-game)
* [Save Indicator](/learn-rxjs/recipes/save-indicator)

### Additional Resources

* [filter](https://rxjs.dev/api/operators/filter) 📰 - Official docs
* [Adding conditional logic with filter](https://egghead.io/lessons/rxjs-adding-conditional-logic-with-filter?course=step-by-step-async-javascript-with-rxjs) 🎥 💵 - John Linquist
* [Filtering operator: filter](https://egghead.io/lessons/rxjs-filtering-operator-filter?course=rxjs-beyond-the-basics-operators-in-depth) 🎥 💵 - André Staltz

***

> 📁 Source Code: <https://github.com/ReactiveX/rxjs/blob/master/packages/rxjs/src/internal/operators/filter.ts>


# find

#### signature: `find(predicate: function)`

## Emit the first item that passes predicate then complete.

***

💡 If you always want the first item emitted, regardless of condition, try [`first()`](/learn-rxjs/operators/filtering/first)!

***

### Examples

**Example 1: Find click inside box, repeat when a click occurs outside of box**

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

```js
// RxJS v6+
import { fromEvent } from 'rxjs';
import { find, repeatWhen, mapTo, startWith, filter } from 'rxjs/operators';

// elem ref
const status = document.getElementById('status');

// streams
const clicks$ = fromEvent(document, 'click');

clicks$
  .pipe(
    find((event: any) => event.target.id === 'box'),
    mapTo('Found!'),
    startWith('Find me!'),
    // reset when click outside box
    repeatWhen(() =>
      clicks$.pipe(filter((event: any) => event.target.id !== 'box'))
    )
  )
  .subscribe(message => (status.innerHTML = message));
```

### Additional Resources

* [find](https://rxjs.dev/api/operators/find) 📰 - Official docs

***

> 📁 Source Code: <https://github.com/ReactiveX/rxjs/blob/master/packages/rxjs/src/internal/operators/find.ts>


# first

#### signature: `first(predicate: function, select: function)`

## Emit the first value or first to pass provided expression.

***

💡 The counterpart to first is [**last**](/learn-rxjs/operators/filtering/last)!

💡 `First` will deliver an EmptyError to the Observer's error callback if the Observable completes before any next notification was sent. If you don't want this behavior, use `take(1)` instead.

***

### Examples

( [example tests](https://github.com/btroncone/learn-rxjs/blob/master/operators/specs/filtering/first-spec.ts) )

**Example 1: First value from sequence**

( [StackBlitz](https://stackblitz.com/edit/typescript-t8hseq?file=index.ts\&devtoolsheight=100) | [jsBin](http://jsbin.com/kayenuxoma/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/uncey4v9/) )

```js
// RxJS v6+
import { from } from 'rxjs';
import { first } from 'rxjs/operators';

const source = from([1, 2, 3, 4, 5]);
//no arguments, emit first value
const example = source.pipe(first());
//output: "First value: 1"
const subscribe = example.subscribe(val => console.log(`First value: ${val}`));
```

**Example 2: First value to pass predicate**

( [StackBlitz](https://stackblitz.com/edit/typescript-bw5byu?file=index.ts\&devtoolsheight=100) | [jsBin](http://jsbin.com/pujowawovu/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/pt36r8cu/) )

```js
// RxJS v6+
import { from } from 'rxjs';
import { first } from 'rxjs/operators';

const source = from([1, 2, 3, 4, 5]);
//emit first item to pass test
const example = source.pipe(first(num => num === 5));
//output: "First to pass test: 5"
const subscribe = example.subscribe(val =>
  console.log(`First to pass test: ${val}`)
);
```

**Example 3: Utilizing default value**

( [StackBlitz](https://stackblitz.com/edit/typescript-2pkzpv?file=index.ts\&devtoolsheight=100) | [jsBin](http://jsbin.com/qoganeleqa/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/owx2jdg1/3/) )

```js
// RxJS v6+
import { from } from 'rxjs';
import { first } from 'rxjs/operators';

const source = from([1, 2, 3, 4, 5]);
//no value will pass, emit default
const example = source.pipe(first(val => val > 5, 'Nothing'));
//output: 'Nothing'
const subscribe = example.subscribe(val => console.log(val));
```

### Additional Resources

* [first](https://rxjs.dev/api/operators/first) 📰 - Official docs
* [Filtering operator: take, first, skip](https://egghead.io/lessons/rxjs-filtering-operators-take-first-skip?course=rxjs-beyond-the-basics-operators-in-depth) 🎥 💵 - André Staltz

***

> 📁 Source Code: <https://github.com/ReactiveX/rxjs/blob/master/packages/rxjs/src/internal/operators/first.ts>


# ignoreElements

#### signature: `ignoreElements(): Observable`

## Ignore everything but complete and error.

### Examples

**Example 1: Ignore all elements from source**

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

```js
// RxJS v6+
import { interval } from 'rxjs';
import { take, ignoreElements } from 'rxjs/operators';

//emit value every 100ms
const source = interval(100);
//ignore everything but complete
const example = source.pipe(take(5), ignoreElements());
//output: "COMPLETE!"
const subscribe = example.subscribe(
  val => console.log(`NEXT: ${val}`),
  val => console.log(`ERROR: ${val}`),
  () => console.log('COMPLETE!')
);
```

**Example 2: Only displaying error**

( [StackBlitz](https://stackblitz.com/edit/typescript-3yxv9z?file=index.ts\&devtoolsheight=100))

```js
// RxJS v6+
import { interval, throwError, of } from 'rxjs';
import { mergeMap, ignoreElements } from 'rxjs/operators';

//emit value every 100ms
const source = interval(100);
//ignore everything but error
const error = source.pipe(
  mergeMap(val => {
    if (val === 4) {
      return throwError(`ERROR AT ${val}`);
    }
    return of(val);
  }),
  ignoreElements()
);
//output: "ERROR: ERROR AT 4"
const subscribe = error.subscribe(
  val => console.log(`NEXT: ${val}`),
  val => console.log(`ERROR: ${val}`),
  () => console.log('SECOND COMPLETE!')
);
```

### Additional Resources

* [ignoreElements](https://rxjs.dev/api/operators/ignoreElements) 📰 - Official docs

***

> 📁 Source Code: <https://github.com/ReactiveX/rxjs/blob/master/packages/rxjs/src/internal/operators/ignoreElements.ts>


# last

\#last

**signature: `last(predicate: function): Observable`**

### Emit the last value emitted from source on completion, based on provided expression.

***

💡 The counterpart to last is [**first**](/learn-rxjs/operators/filtering/first)!

***

#### Examples

**Example 1: Last value in sequence**

( [StackBlitz](https://stackblitz.com/edit/typescript-ma7knv?file=index.ts\&devtoolsheight=100) | [jsBin](http://jsbin.com/pevaqeloki/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/b05r434a/) )

```js
// RxJS v6+
import { from } from 'rxjs';
import { last } from 'rxjs/operators';

const source = from([1, 2, 3, 4, 5]);
//no arguments, emit last value
const example = source.pipe(last());
//output: "Last value: 5"
const subscribe = example.subscribe(val => console.log(`Last value: ${val}`));
```

**Example 2: Last value to pass predicate**

( [StackBlitz](https://stackblitz.com/edit/typescript-tk42hj?file=index.ts\&devtoolsheight=100) | [jsBin](http://jsbin.com/yagexuwari/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/pkx2btsh/) )

```js
// RxJS v6+
import { from } from 'rxjs';
import { last } from 'rxjs/operators';

const source = from([1, 2, 3, 4, 5]);
//emit last even number
const exampleTwo = source.pipe(last(num => num % 2 === 0));
//output: "Last to pass test: 4"
const subscribeTwo = exampleTwo.subscribe(val =>
  console.log(`Last to pass test: ${val}`)
);
```

**Example 3: Last with default value**

( [StackBlitz](https://stackblitz.com/edit/typescript-nrc1an?file=index.ts\&devtoolsheight=100) | [jsBin](http://jsbin.com/fudubebabi/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/L7fbx3vp/) )

```js
// RxJS v6+
import { from } from 'rxjs';
import { last } from 'rxjs/operators';

const source = from([1, 2, 3, 4, 5]);
//no values will pass given predicate, emit default
const exampleTwo = source.pipe(last(v => v > 5, 'Nothing!'));
//output: 'Nothing!'
const subscribeTwo = exampleTwo.subscribe(val => console.log(val));
```

#### Additional Resources

* [last](https://rxjs.dev/api/operators/last) 📰 - Official docs
* [Filtering operator: takeLast, last](https://egghead.io/lessons/rxjs-filtering-operators-takelast-last?course=rxjs-beyond-the-basics-operators-in-depth) 🎥 💵 - André Staltz

***

> 📁 Source Code: <https://github.com/ReactiveX/rxjs/blob/master/packages/rxjs/src/internal/operators/last.ts>


# sample

#### signature: `sample(sampler: Observable): Observable`

## Sample from source when provided observable emits.

### Examples

**Example 1: Sample source every 2 seconds**

( [StackBlitz](https://stackblitz.com/edit/typescript-envpsp?file=index.ts\&devtoolsheight=100) | [jsBin](http://jsbin.com/gemebopifu/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/8wsbuvjb/) )

```js
// RxJS v6+
import { interval } from 'rxjs';
import { sample } from 'rxjs/operators';

//emit value every 1s
const source = interval(1000);
//sample last emitted value from source every 2s
const example = source.pipe(sample(interval(2000)));
//output: 2..4..6..8..
const subscribe = example.subscribe(val => console.log(val));
```

**Example 2: Sample source when interval emits**

( [StackBlitz](https://stackblitz.com/edit/typescript-sgat7t?file=index.ts\&devtoolsheight=100) | [jsBin](http://jsbin.com/cunicepube/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/b33kg9dn/) )

```js
// RxJS v6+
import { interval, zip, from } from 'rxjs';
import { sample } from 'rxjs/operators';

const source = zip(
  //emit 'Joe', 'Frank' and 'Bob' in sequence
  from(['Joe', 'Frank', 'Bob']),
  //emit value every 2s
  interval(2000)
);
//sample last emitted value from source every 2.5s
const example = source.pipe(sample(interval(2500)));
//output: ["Joe", 0]...["Frank", 1]...........
const subscribe = example.subscribe(val => console.log(val));
```

**Example 3: Distinguish between drag and click**

From [Stack Overflow](https://stackoverflow.com/a/44865892/2774547) By [Dorus](https://stackoverflow.com/users/402027/dorus)

( [StackBlitz](https://stackblitz.com/edit/typescript-vk8p3e?file=index.ts\&devtoolsheight=100) | [jsBin](http://jsbin.com/riwipicilo/1/edit?html,js,console,output) | [jsFiddle](https://jsfiddle.net/6yy6q0Lo/1/) )

```js
// RxJS v6+
import { fromEvent, merge } from 'rxjs';
import { sample, mapTo } from 'rxjs/operators';

const listener = merge(
  fromEvent(document, 'mousedown').pipe(mapTo(false)),
  fromEvent(document, 'mousemove').pipe(mapTo(true))
)
  .pipe(sample(fromEvent(document, 'mouseup')))
  .subscribe(isDragging => {
    console.log('Were you dragging?', isDragging);
  });
```

### Additional Resources

* [sample](https://rxjs.dev/api/operators/sample) 📰 - Official docs

***

> 📁 Source Code: <https://github.com/ReactiveX/rxjs/blob/master/packages/rxjs/src/internal/operators/sample.ts>


# single

#### signature: `single(a: Function): Observable`

## Emit single item that passes expression.

### Examples

**Example 1: Emit first number passing predicate**

( [StackBlitz](https://stackblitz.com/edit/typescript-qhynlr?file=index.ts\&devtoolsheight=100) | [jsBin](http://jsbin.com/solecibuza/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/26r5y90s/) )

```js
// RxJS v6+
import { from } from 'rxjs';
import { single } from 'rxjs/operators';

//emit (1,2,3,4,5)
const source = from([1, 2, 3, 4, 5]);
//emit one item that matches predicate
const example = source.pipe(single(val => val === 4));
//output: 4
const subscribe = example.subscribe(val => console.log(val));
```

### Additional Resources

* [single](https://rxjs.dev/api/operators/single) 📰 - Official docs

***

> 📁 Source Code: <https://github.com/ReactiveX/rxjs/blob/master/packages/rxjs/src/internal/operators/single.ts>


# skip

#### signature: `skip(the: Number): Observable`

## Skip the provided number of emitted values.

### Why use `skip`?

Skip allows you to ignore the first x emissions from the source. Generally `skip` is used when you have an observable that always emits certain values on subscription that you wish to ignore. Perhaps those first few aren't needed or you are subscribing to a `Replay` or `BehaviorSubject` and do not need to act on the initial values. Reach for `skip` if you are only concerned about later emissions.

You could mimic `skip` by using [`filter`](/learn-rxjs/operators/filtering/filter) with indexes. Ex. `.filter((val, index) => index > 1)`

### Examples

**Example 1: Skipping values before emission**

( [StackBlitz](https://stackblitz.com/edit/typescript-o5ydjf?file=index.ts\&devtoolsheight=100))

```js
// RxJS v6+
import { interval } from 'rxjs';
import { skip } from 'rxjs/operators';

//emit every 1s
const source = interval(1000);
//skip the first 5 emitted values
const example = source.pipe(skip(5));
//output: 5...6...7...8........
const subscribe = example.subscribe(val => console.log(val));
```

#### Example 2: Short hand for a specific filter use case

( [StackBlitz](https://stackblitz.com/edit/typescript-yl3ap1?file=index.ts\&devtoolsheight=100) | [jsBin](http://jsbin.com/judamurego/edit?js,console) | [jsFiddle](https://jsfiddle.net/ElHuy/4jswLn3z/) )

```js
// RxJS v6+
import { from } from 'rxjs';
import { skip, filter } from 'rxjs/operators';

const numArrayObs = from([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);

// 3,4,5...
const skipObs = numArrayObs.pipe(skip(2)).subscribe(console.log);

// 3,4,5...
const filterObs = numArrayObs
  .pipe(filter((val, index) => index > 1))
  .subscribe(console.log);

//Same output!
```

### Additional Resources

* [skip](https://rxjs.dev/api/operators/skip) 📰 - Official docs
* [Filtering operator: take, first, skip](https://egghead.io/lessons/rxjs-filtering-operators-take-first-skip?course=rxjs-beyond-the-basics-operators-in-depth) 🎥 💵 - André Staltz

***

> 📁 Source Code: <https://github.com/ReactiveX/rxjs/blob/master/packages/rxjs/src/internal/operators/skip.ts>


# skipUntil

\####signature: `skipUntil(the: Observable): Observable`

## Skip emitted values from source until provided observable emits.

### Examples

**Example 1: Skip until observable emits**

( [StackBlitz](https://stackblitz.com/edit/typescript-gs4mps?file=index.ts\&devtoolsheight=100) | [jsBin](http://jsbin.com/tapizososu/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/xLu8nf77/) )

```js
// RxJS v6+
import { interval, timer } from 'rxjs';
import { skipUntil } from 'rxjs/operators';

//emit every 1s
const source = interval(1000);
//skip emitted values from source until inner observable emits (6s)
const example = source.pipe(skipUntil(timer(6000)));
//output: 5...6...7...8........
const subscribe = example.subscribe(val => console.log(val));
```

### Additional Resources

* [skipUntil](https://rxjs.dev/api/operators/skipUntil) 📰 - Official docs

***

> 📁 Source Code: <https://github.com/ReactiveX/rxjs/blob/master/packages/rxjs/src/internal/operators/skipUntil.ts>


# skipWhile

#### signature: `skipWhile(predicate: Function): Observable`

## Skip emitted values from source until provided expression is false.

### Examples

**Example 1: Skip while values below threshold**

( [StackBlitz](https://stackblitz.com/edit/typescript-p5kapz?file=index.ts\&devtoolsheight=100) | [jsBin](http://jsbin.com/bemikuleya/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/3ymfxb09/) )

```js
// RxJS v6+
import { interval } from 'rxjs';
import { skipWhile } from 'rxjs/operators';

//emit every 1s
const source = interval(1000);
//skip emitted values from source while value is less than 5
const example = source.pipe(skipWhile(val => val < 5));
//output: 5...6...7...8........
const subscribe = example.subscribe(val => console.log(val));
```

### Additional Resources

* [skipWhile](https://rxjs.dev/api/operators/skipWhile) 📰 - Official docs

***

> 📁 Source Code: <https://github.com/ReactiveX/rxjs/blob/master/packages/rxjs/src/internal/operators/skipWhile.ts>


# take

#### signature: `take(count: number): Observable`

## Emit provided number of values before completing.

### Why use `take`?

When you are interested in only the first emission, you want to use `take`. Maybe you want to see what the user first clicked on when they entered the page, or you would want to subscribe to the click event and just take the first emission. Another use-case is when you need to take a snapshot of data at a particular point in time but do not require further emissions. For example, a stream of user token updates, or a route guard based on a stream in an Angular application.

***

💡 If you want to take a variable number of values based on some logic, or another observable, you can use [takeUntil](/learn-rxjs/operators/filtering/takeuntil) or [takeWhile](/learn-rxjs/operators/filtering/takewhile)!

💡 `take` is the opposite of [`skip`](/learn-rxjs/operators/filtering/skip) where `take` will take the first *n* number of emissions while `skip` will skip the first *n* number of emissions.

***

### Examples

**Example 1: Take 1 value from source**

( [StackBlitz](https://stackblitz.com/edit/typescript-uk92ax?file=index.ts\&devtoolsheight=100) | [jsBin](http://jsbin.com/vaxitupiwi/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/f9bz0tr3/) )

```js
// RxJS v6+
import { of } from 'rxjs';
import { take } from 'rxjs/operators';

//emit 1,2,3,4,5
const source = of(1, 2, 3, 4, 5);
//take the first emitted value then complete
const example = source.pipe(take(1));
//output: 1
const subscribe = example.subscribe(val => console.log(val));
```

**Example 2: Take the first 5 values from source**

( [StackBlitz](https://stackblitz.com/edit/typescript-3ujuth?file=index.ts\&devtoolsheight=100) | [jsBin](http://jsbin.com/kexenuzulu/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/g1fhxgua/) )

```js
// RxJS v6+
import { interval } from 'rxjs';
import { take } from 'rxjs/operators';

//emit value every 1s
const interval$ = interval(1000);
//take the first 5 emitted values
const example = interval$.pipe(take(5));
//output: 0,1,2,3,4
const subscribe = example.subscribe(val => console.log(val));
```

**Example 3: Taking first click location**

([StackBlitz](https://stackblitz.com/edit/typescript-8g9xt5?file=index.ts\&devtoolsheight=50) | [jsFiddle](https://jsfiddle.net/ElHuy/9c5j064x/))

```html
<div id="locationDisplay">
  Where would you click first?
</div>
```

```js
// RxJS v6+
import { fromEvent } from 'rxjs';
import { take, tap } from 'rxjs/operators';

const oneClickEvent = fromEvent(document, 'click').pipe(
  take(1),
  tap(v => {
    document.getElementById(
      'locationDisplay'
    ).innerHTML = `Your first click was on location ${v.screenX}:${v.screenY}`;
  })
);

const subscribe = oneClickEvent.subscribe();
```

### Related Recipes

* [Battleship Game](/learn-rxjs/recipes/battleship-game)
* [Memory Game](/learn-rxjs/recipes/memory-game)

### Additional Resources

* [take](https://rxjs.dev/api/operators/take) 📰 - Official docs
* [Filtering operator: take, first, skip](https://egghead.io/lessons/rxjs-filtering-operators-take-first-skip?course=rxjs-beyond-the-basics-operators-in-depth) 🎥 💵 - André Staltz

***

> 📁 Source Code: <https://github.com/ReactiveX/rxjs/blob/master/packages/rxjs/src/internal/operators/take.ts>


# takeLast

#### signature: `takeLast(count: number): Observable`

## Emit the last n emitted values before completion

***

💡 If you want only the last emission from multiple observables, on completion of multiple observables, try [forkJoin](/learn-rxjs/operators/combination/forkjoin)!

***

### Examples

**Example 1: take the last 2 emitted values before completion**

( [StackBlitz](https://stackblitz.com/edit/typescript-zss7oo?file=index.ts\&devtoolsheight=100) )

```js
// RxJS v6+
import { of } from 'rxjs';
import { takeLast } from 'rxjs/operators';

const source = of('Ignore', 'Ignore', 'Hello', 'World!');
// take the last 2 emitted values
const example = source.pipe(takeLast(2));
// Hello, World!
const subscribe = example.subscribe(val => console.log(val));
```

### Additional Resources

* [takeLast](https://rxjs-dev.firebaseapp.com/api/operators/takeLast) 📰 - Official docs

***

> 📁 Source Code: <https://github.com/ReactiveX/rxjs/blob/master/packages/rxjs/src/internal/operators/takeLast.ts>


# takeUntil

#### signature: `takeUntil(notifier: Observable): Observable`

## Emit values until provided observable emits.

***

💡 If you only need a specific number of values, try [take](/learn-rxjs/operators/filtering/take)!

***

### Why use `takeUntil`?

Consider a day at your workplace: You're anticipating an important email, but you've decided that once the clock hits 5 pm, you're clocking out, regardless of whether you've received that email or not. In this RxJS analogy, the anticipation of the email is one observable, while the 5 pm clock-out time is another. The `takeUntil` operator ensures you're alert for the email's potential arrival, but the moment 5 pm arrives, you stop checking (unsubscribe).

In real-world applications, think of a scenario where you're monitoring server responses on a dashboard. However, you want this monitoring to cease once a specific "Stop Monitoring" button is clicked. That's where `takeUntil` shines.

In the context of Angular, `takeUntil` is particularly handy for auto-unsubscribing from observables when a component is destroyed. This is achieved by leveraging the `ngOnDestroy` lifecycle hook. You'd typically create a `Subject`, often named `destroy$`, and use it with `takeUntil`:

```typescript
private destroy$ = new Subject<void>();

observable$
  .pipe(takeUntil(this.destroy$))
  .subscribe(data => console.log(data));

ngOnDestroy() {
  this.destroy$.next();
  this.destroy$.complete();
}
```

With this setup, as soon as the `ngOnDestroy` method is called (when the component is about to be destroyed), the observables using `takeUntil` with the `destroy$` subject will automatically unsubscribe, ensuring that no unwanted memory leaks or unexpected behavior occurs.

### Examples

**Example 1: Take values until timer emits**

( [StackBlitz](https://stackblitz.com/edit/typescript-ujwjbg?file=index.ts\&devtoolsheight=100) | [jsBin](http://jsbin.com/yevuhukeja/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/zbe9dzb9/) )

```js
// RxJS v6+
import { interval, timer } from 'rxjs';
import { takeUntil } from 'rxjs/operators';

//emit value every 1s
const source = interval(1000);
//after 5 seconds, emit value
const timer$ = timer(5000);
//when timer emits after 5s, complete source
const example = source.pipe(takeUntil(timer$));
//output: 0,1,2,3
const subscribe = example.subscribe(val => console.log(val));
```

**Example 2: Take the first 5 even numbers**

( [StackBlitz](https://stackblitz.com/edit/typescript-djhv7s?file=index.ts\&devtoolsheight=100) | [jsBin](http://jsbin.com/doquqecara/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/0dLeksLe/) )

```js
// RxJS v6+
import { interval } from 'rxjs/observable/interval';
import { takeUntil, filter, scan, map, withLatestFrom } from 'rxjs/operators';

//emit value every 1s
const source = interval(1000);
//is number even?
const isEven = val => val % 2 === 0;
//only allow values that are even
const evenSource = source.pipe(filter(isEven));
//keep a running total of the number of even numbers out
const evenNumberCount = evenSource.pipe(scan((acc, _) => acc + 1, 0));
//do not emit until 5 even numbers have been emitted
const fiveEvenNumbers = evenNumberCount.pipe(filter(val => val > 5));

const example = evenSource.pipe(
  //also give me the current even number count for display
  withLatestFrom(evenNumberCount),
  map(([val, count]) => `Even number (${count}) : ${val}`),
  //when five even numbers have been emitted, complete source observable
  takeUntil(fiveEvenNumbers)
);
/*
	Even number (1) : 0,
  Even number (2) : 2
	Even number (3) : 4
	Even number (4) : 6
	Even number (5) : 8
*/
const subscribe = example.subscribe(val => console.log(val));
```

**Example 3: Take mouse events on mouse down until mouse up**

( [StackBlitz](https://stackblitz.com/edit/rxjs-ug2ezf?file=index.ts\&devtoolsheight=50) )

```js
// RxJS v6+
import { fromEvent } from 'rxjs';
import { takeUntil, mergeMap, map } from 'rxjs/operators';

const mousedown$ = fromEvent(document, 'mousedown');
const mouseup$ = fromEvent(document, 'mouseup');
const mousemove$ = fromEvent(document, 'mousemove');

// after mousedown, take position until mouse up
mousedown$
  .pipe(
    mergeMap(_ => {
      return mousemove$.pipe(
        map((e: any) => ({
          x: e.clientX,
          y: e.clientY
        })),
        // complete inner observable on mouseup event
        takeUntil(mouseup$)
      );
    })
  )
  .subscribe(console.log);
```

### Related Recipes

* [Lockscreen](/learn-rxjs/recipes/lockscreen)
* [Space Invaders Game](/learn-rxjs/recipes/space-invaders-game)
* [Swipe To Refresh](/learn-rxjs/recipes/swipe-to-refresh)

### Additional Resources

* [takeUntil](https://rxjs.dev/api/operators/takeUntil) 📰 - Official docs
* [Avoiding takeUntil leaks](https://blog.angularindepth.com/rxjs-avoiding-takeuntil-leaks-fb5182d047ef) - Angular in Depth
* [Stopping a stream with takeUntil](https://egghead.io/lessons/rxjs-stopping-a-stream-with-takeuntil?course=step-by-step-async-javascript-with-rxjs) 🎥 💵 - John Linquist

***

> 📁 Source Code: <https://github.com/ReactiveX/rxjs/blob/master/packages/rxjs/src/internal/operators/takeUntil.ts>


# takeWhile

#### signature: `takeWhile(predicate: function(value, index): boolean, inclusive?: boolean): Observable`

## Emit values until provided expression is false.

***

💡 When the optional `inclusive` parameter is set to `true` it will also emit the first item that didn't pass the predicate.

***

### Examples

**Example 1: Take values under limit**

( [StackBlitz](https://stackblitz.com/edit/typescript-af3hdf?file=index.ts\&devtoolsheight=100) | [jsBin](http://jsbin.com/zanefaqexu/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/yakd4jgc/) )

```js
// RxJS v6+
import { of } from 'rxjs';
import { takeWhile } from 'rxjs/operators';

//emit 1,2,3,4,5
const source$ = of(1, 2, 3, 4, 5);

//allow values until value from source is greater than 4, then complete
source$
  .pipe(takeWhile(val => val <= 4))
  // log: 1,2,3,4
  .subscribe(val => console.log(val));
```

**Example 2: (v6.4+) takeWhile with inclusive flag**

( [StackBlitz](https://stackblitz.com/edit/typescript-3bwfup?file=index.ts\&devtoolsheight=100) )

```js
// RxJS v6.4+
import { of } from 'rxjs';
import { takeWhile, filter } from 'rxjs/operators';

const source$ = of(1, 2, 3, 9);

source$
  // with inclusive flag, the value causing the predicate to return false will also be emitted
  .pipe(takeWhile(val => val <= 3, true))
  // log: 1, 2, 3, 9
  .subscribe(console.log);
```

**Example 3: Difference between `takeWhile` and** [**`filter`**](/learn-rxjs/operators/filtering/filter)

( [StackBlitz](https://stackblitz.com/edit/typescript-roozza?file=index.ts\&devtoolsheight=100) | [jsBin](http://jsbin.com/yatoqurewi/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/r497jgw3/4/) )

```js
// RxJS v6+
import { of } from 'rxjs';
import { takeWhile, filter } from 'rxjs/operators';

// emit 3, 3, 3, 9, 1, 4, 5, 8, 96, 3, 66, 3, 3, 3
const source$ = of(3, 3, 3, 9, 1, 4, 5, 8, 96, 3, 66, 3, 3, 3);

// allow values until value from source equals 3, then complete
source$
  .pipe(takeWhile(it => it === 3))
  // log: 3, 3, 3
  .subscribe(val => console.log('takeWhile', val));

source$
  .pipe(filter(it => it === 3))
  // log: 3, 3, 3, 3, 3, 3, 3
  .subscribe(val => console.log('filter', val));
```

### Related Recipes

* [Alphabet Invasion Game](/learn-rxjs/recipes/alphabet-invasion-game)
* [Battleship Game](/learn-rxjs/recipes/battleship-game)
* [Breakout Game](/learn-rxjs/recipes/breakout-game)
* [Car Racing Game](/learn-rxjs/recipes/car-racing-game)
* [Catch The Dot Game](/learn-rxjs/recipes/catch-the-dot-game)
* [Click Ninja Game](/learn-rxjs/recipes/click-ninja-game)
* [Flappy Bird Game](/learn-rxjs/recipes/flappy-bird-game)
* [Mine Sweeper Game](/learn-rxjs/recipes/mine-sweeper-game)
* [Platform Jumper Game](/learn-rxjs/recipes/platform-jumper-game)
* [Smart Counter](/learn-rxjs/recipes/smartcounter)
* [Swipe To Refresh](/learn-rxjs/recipes/swipe-to-refresh)
* [Tetris Game](/learn-rxjs/recipes/tetris-game)
* [Uncover Image Game](/learn-rxjs/recipes/uncover-image-game)

### Additional Resources

* [takeWhile](https://rxjs-dev.firebaseapp.com/api/operators/takeWhile) 📰 - Official docs
* [Completing a stream with takeWhile](https://egghead.io/lessons/rxjs-completing-a-stream-with-takewhile?course=step-by-step-async-javascript-with-rxjs) 🎥 💵 - John Linquist

***

> 📁 Source Code: <https://github.com/ReactiveX/rxjs/blob/master/packages/rxjs/src/internal/operators/takeWhile.ts>


# throttle

#### signature: `throttle(durationSelector: function(value): Observable | Promise): Observable`

## Emit value on the leading edge of an interval, but suppress new values until `durationSelector` has completed.

### Examples

**Example 1: Throttle for 2 seconds, based on second observable**

( [StackBlitz](https://stackblitz.com/edit/typescript-pfcmjw?file=index.ts\&devtoolsheight=100) | [jsBin](http://jsbin.com/wohefujipo/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/h8na4m0p/) )

```js
// RxJS v6+
import { interval } from 'rxjs';
import { throttle } from 'rxjs/operators';

//emit value every 1 second
const source = interval(1000);
//throttle for 2 seconds, emit latest value
const example = source.pipe(throttle(val => interval(2000)));
//output: 0...3...6...9
const subscribe = example.subscribe(val => console.log(val));
```

**Example 2: Throttle with promise**

( [StackBlitz](https://stackblitz.com/edit/typescript-g74v3q?file=index.ts\&devtoolsheight=100) | [jsBin](http://jsbin.com/seyaguwunu/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/w5Lbzz9f/) )

```js
// RxJS v6+
import { interval } from 'rxjs';
import { throttle, map } from 'rxjs/operators';

//emit value every 1 second
const source = interval(1000);
//incrementally increase the time to resolve based on source
const promise = val =>
  new Promise(resolve =>
    setTimeout(() => resolve(`Resolved: ${val}`), val * 100)
  );
//when promise resolves emit item from source
const example = source.pipe(
  throttle(promise),
  map(val => `Throttled off Promise: ${val}`)
);

const subscribe = example.subscribe(val => console.log(val));
```

### Additional Resources

* [throttle](https://rxjs.dev/api/operators/throttle) 📰 - Official docs
* [Filtering operator: throttle and throttleTime](https://egghead.io/lessons/rxjs-filtering-operators-throttle-and-throttletime?course=rxjs-beyond-the-basics-operators-in-depth) 🎥 💵 - André Staltz

***

> 📁 Source Code: <https://github.com/ReactiveX/rxjs/blob/master/packages/rxjs/src/internal/operators/throttle.ts>


# throttleTime

#### signature: `throttleTime(duration: number, scheduler: Scheduler, config: ThrottleConfig): Observable`

## Emit first value then ignore for specified duration

### Examples

**Example 1: Emit first value, ignore for 5s window**

( [StackBlitz](https://stackblitz.com/edit/typescript-en2zqe?file=index.ts\&devtoolsheight=100) )

```js
// RxJS v6+
import { interval } from 'rxjs';
import { throttleTime } from 'rxjs/operators';

// emit value every 1 second
const source = interval(1000);
/*
  emit the first value, then ignore for 5 seconds. repeat...
*/
const example = source.pipe(throttleTime(5000));
// output: 0...6...12
const subscribe = example.subscribe(val => console.log(val));
```

**Example 2: Emit on trailing edge using config**

( [StackBlitz](https://stackblitz.com/edit/typescript-5rwl6i?file=index.ts\&devtoolsheight=100) )

```js
// RxJS v6+
import { interval, asyncScheduler } from 'rxjs';
import { throttleTime } from 'rxjs/operators';

const source = interval(1000);
/*
  emit the first value, then ignore for 5 seconds. repeat...
*/
const example = source.pipe(
  throttleTime(5000, asyncScheduler, { trailing: true })
);
// output: 5...11...17
const subscribe = example.subscribe(val => console.log(val));
```

### Related Recipes

* [Horizontal Scroll Indicator](/learn-rxjs/recipes/horizontal-scroll-indicator)
* [Lockscreen](/learn-rxjs/recipes/lockscreen)

### Additional Resources

* [throttleTime](https://rxjs.dev/api/operators/throttleTime) 📰 - Official docs
* [Filtering operator: throttle and throttleTime](https://egghead.io/lessons/rxjs-filtering-operators-throttle-and-throttletime?course=rxjs-beyond-the-basics-operators-in-depth) 🎥 💵 - André Staltz
* [Time based operators comparison](/learn-rxjs/concepts/time-based-operators-comparison)

***

> 📁 Source Code: <https://github.com/ReactiveX/rxjs/blob/master/packages/rxjs/src/internal/operators/throttleTime.ts>


# Transformation

Transforming values as they pass through the operator chain is a common task. These operators provide transformation techniques for nearly any use-case you will encounter.

{% hint style="info" %}
New to transformation operators? Check out the article [Get started transforming streams with map, pluck, and mapTo](/learn-rxjs/concepts/get-started-transforming)!
{% endhint %}

## Contents

* [buffer](/learn-rxjs/operators/transformation/buffer)
* [bufferCount](/learn-rxjs/operators/transformation/buffercount)
* [bufferTime](/learn-rxjs/operators/transformation/buffertime) ⭐
* [bufferToggle](/learn-rxjs/operators/transformation/buffertoggle)
* [bufferWhen](/learn-rxjs/operators/transformation/bufferwhen)
* [concatMap](/learn-rxjs/operators/transformation/concatmap) ⭐
* [concatMapTo](/learn-rxjs/operators/transformation/concatmapto)
* [exhaustMap](/learn-rxjs/operators/transformation/exhaustmap)
* [expand](/learn-rxjs/operators/transformation/expand)
* [groupBy](/learn-rxjs/operators/transformation/groupby)
* [map](/learn-rxjs/operators/transformation/map) ⭐
* [mapTo](/learn-rxjs/operators/transformation/mapto)
* [mergeMap / flatMap](/learn-rxjs/operators/transformation/mergemap) ⭐
* [mergeScan](/learn-rxjs/operators/transformation/mergescan)
* [partition](/learn-rxjs/operators/transformation/partition)
* [pluck](/learn-rxjs/operators/transformation/pluck)
* [reduce](/learn-rxjs/operators/transformation/reduce)
* [scan](/learn-rxjs/operators/transformation/scan) ⭐
* [switchMap](/learn-rxjs/operators/transformation/switchmap) ⭐
* [switchMapTo](/learn-rxjs/operators/transformation/switchmapto)
* [toArray](/learn-rxjs/operators/transformation/toarray)
* [window](/learn-rxjs/operators/transformation/window)
* [windowCount](/learn-rxjs/operators/transformation/windowcount)
* [windowTime](/learn-rxjs/operators/transformation/windowtime)
* [windowToggle](/learn-rxjs/operators/transformation/windowtoggle)
* [windowWhen](/learn-rxjs/operators/transformation/windowwhen)

⭐ - *commonly used*


# buffer

#### signature: `buffer(closingNotifier: Observable): Observable`

## Collect output values until provided observable emits, emit as array.

### Why use `buffer`?

The buffer operator in RxJS stands out for its ability to accumulate emitted values into an array until a specified notifier emits. Think of it as a "collect and release" mechanism. This aligns well with use cases where you want to group events based on a certain condition, such as time or user actions.

Buffer shines in scenarios like batching multiple events together before processing, which can optimize performance and reduce workload. For example, when monitoring clicks on a web page, buffer can gather a series of clicks before sending them for analytics, rather than doing so individually.

However, keep in mind that buffer may not be the best fit when you require immediate processing of each emitted value. One way to think about this is "buffer is about batching". Remember, buffer is all about accumulating and releasing values based on specific triggers, making it a powerful tool for managing grouped events.

### Examples

**Example 1: Using buffer to recognize double clicks**

( [StackBlitz](https://stackblitz.com/edit/typescript-x5zyn5?file=index.ts\&devtoolsheight=50))

```js
// RxJS v6+
import { fromEvent } from 'rxjs';
import { buffer, filter, throttleTime } from 'rxjs/operators';

// streams
const clicks$ = fromEvent(document, 'click');

/*
Collect clicks that occur, after 250ms emit array of clicks
*/
clicks$
  .pipe(
    buffer(clicks$.pipe(throttleTime(250))),
    // if array is greater than 1, double click occured
    filter(clickArray => clickArray.length > 1)
  )
  .subscribe(() => console.log('Double Click!'));
```

**Example 2: Buffer until document click**

( [StackBlitz](https://stackblitz.com/edit/typescript-nwp2cl?file=index.ts\&devtoolsheight=50) | [jsBin](http://jsbin.com/fazimarajo/edit?js,console,output) | [jsFiddle](https://jsfiddle.net/btroncone/7451s67k/) )

```js
// RxJS v6+
import { interval, fromEvent } from 'rxjs';
import { buffer } from 'rxjs/operators';

//Create an observable that emits a value every second
const myInterval = interval(1000);
//Create an observable that emits every time document is clicked
const bufferBy = fromEvent(document, 'click');
/*
Collect all values emitted by our interval observable until we click document. This will cause the bufferBy Observable to emit a value, satisfying the buffer. Pass us all collected values since last buffer as an array.
*/
const myBufferedInterval = myInterval.pipe(buffer(bufferBy));
//Print values to console
//ex. output: [1,2,3] ... [4,5,6,7,8]
const subscribe = myBufferedInterval.subscribe(val =>
  console.log(' Buffered Values:', val)
);
```

### Related Recipes

* [Game Loop](/learn-rxjs/recipes/gameloop)

### Additional Resources

* [buffer](https://rxjs-dev.firebaseapp.com/api/operators/buffer) 📰 - Official docs
* [Transformation operator: buffer](https://egghead.io/lessons/rxjs-transformation-operator-buffer?course=rxjs-beyond-the-basics-operators-in-depth) 🎥 💵 - André Staltz

***

> 📁 Source Code: <https://github.com/ReactiveX/rxjs/blob/master/packages/rxjs/src/internal/operators/buffer.ts>


# bufferCount

#### signature: `bufferCount(bufferSize: number, startBufferEvery: number = null): Observable`

## Collect emitted values until provided number is fulfilled, emit as array.

### Why use `bufferCount`?

The key distinction between bufferCount and other buffering operators lies in its count-based buffering approach. Upon reaching the specified count of emissions, bufferCount groups and emits the values as an array. Think of it as collecting items in groups of the specified count.

This operator proves advantageous in scenarios where processing data in chunks is more efficient, such as bulk updates or batch processing. By contrast, the buffer operator relies on a closing notifier to define the buffering window, which may not suit all use cases.

Keep in mind, though, that bufferCount may not be the best choice when the buffering strategy requires time-based or event-driven windows. In such instances, consider using [buffer](/learn-rxjs/operators/transformation/buffer) or [buffertime](https://github.com/btroncone/learn-rxjs/blob/master/operators/transformation/bufferTime.md) instead. Remember, bufferCount organizes values based on emission count, as illustrated clearly in the first example.

Exercise caution in situations where buffering strategy plays a critical role in the desired output, as choosing the wrong operator might lead to unexpected behavior. Familiarize yourself with the various buffering operators to make informed decisions based on your specific requirements.

### Examples

**Example 1: Collect buffer and emit after specified number of values**

( [StackBlitz](https://stackblitz.com/edit/typescript-osryhu?file=index.ts\&devtoolsheight=50) | [jsBin](http://jsbin.com/suveqaromu/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/ky9myc5b/) )

```js
// RxJS v6+
import { interval } from 'rxjs';
import { bufferCount } from 'rxjs/operators';

//Create an observable that emits a value every second
const source = interval(1000);
//After three values are emitted, pass on as an array of buffered values
const bufferThree = source.pipe(bufferCount(3));
//Print values to console
//ex. output [0,1,2]...[3,4,5]
const subscribe = bufferThree.subscribe(val =>
  console.log('Buffered Values:', val)
);
```

**Example 2: Overlapping buffers**

( [StackBlitz](https://stackblitz.com/edit/typescript-vvccar?file=index.ts\&devtoolsheight=100) | [jsBin](http://jsbin.com/kiloxiraya/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/3c67qcz1/) )

```js
// RxJS v6+
import { interval } from 'rxjs';
import { bufferCount } from 'rxjs/operators';

//Create an observable that emits a value every second
const source = interval(1000);
/*
bufferCount also takes second argument, when to start the next buffer
for instance, if we have a bufferCount of 3 but second argument (startBufferEvery) of 1:
1st interval value:
buffer 1: [0]
2nd interval value:
buffer 1: [0,1]
buffer 2: [1]
3rd interval value:
buffer 1: [0,1,2] Buffer of 3, emit buffer
buffer 2: [1,2]
buffer 3: [2]
4th interval value:
buffer 2: [1,2,3] Buffer of 3, emit buffer
buffer 3: [2, 3]
buffer 4: [3]
*/
const bufferEveryOne = source.pipe(bufferCount(3, 1));
//Print values to console
const subscribe = bufferEveryOne.subscribe(val =>
  console.log('Start Buffer Every 1:', val)
);
```

**Example 3: Last n keyboard presses tracking**

( [StackBlitz](https://stackblitz.com/edit/rxjs-buffecount-keypresses-tracking?file=index.ts\&devtoolsheight=50) )

```js
// RxJS v6+
import { fromEvent, of } from 'rxjs';
import { bufferCount, map, mergeMap, tap } from 'rxjs/operators';

const fakeKeyPressesPost = keypresses =>
  of(201).pipe(
    tap(_ => {
      console.log(`received key presses are: ${keypresses}`);
      document.getElementById('output').innerText = keypresses;
    })
  );

fromEvent(document, 'keydown')
  .pipe(
    map((e: KeyboardEvent) => e.key),
    bufferCount(5),
    mergeMap(fakeKeyPressesPost)
  )
  .subscribe();
```

### Additional Resources

* [bufferCount](https://rxjs.dev/api/operators/bufferCount) 📰 - Official docs

***

> 📁 Source Code: <https://github.com/ReactiveX/rxjs/blob/master/packages/rxjs/src/internal/operators/bufferCount.ts>


# bufferTime

#### signature: `bufferTime(bufferTimeSpan: number, bufferCreationInterval: number, scheduler: Scheduler): Observable`

## Collect emitted values until provided time has passed, emit as array.

### Why use `bufferTime`?

The key distinction between `bufferTime` and other buffering operators lies in its time-based buffering approach. `bufferTime` accumulates values from the source observable in an array over a specified time duration before emitting the buffered array.

This operator is particularly well-suited for scenarios where you need to batch or throttle emissions from high-frequency observables, such as monitoring user interactions, tracking mouse movements, or dealing with rapidly updating data streams. `bufferTime` provides an efficient way to handle and process these emissions in a more manageable, time-based manner.

Remember, `bufferTime` allows you to manage data emissions effectively by collecting and emitting them in time-based batches, as illustrated in the first example. Be mindful of its implications, though, and choose the right operator according to your specific use case.

### Examples

**Example 1: Buffer for 2 seconds**

( [StackBlitz](https://stackblitz.com/edit/typescript-haqxd1?file=index.ts\&devtoolsheight=50))

```js
// RxJS v6+
import { interval } from 'rxjs';
import { bufferTime } from 'rxjs/operators';

//Create an observable that emits a value every 500ms
const source = interval(500);
//After 2 seconds have passed, emit buffered values as an array
const example = source.pipe(bufferTime(2000));
//Print values to console
//ex. output [0,1,2]...[3,4,5,6]
const subscribe = example.subscribe(val =>
  console.log('Buffered with Time:', val)
);
```

**Example 2: Multiple active buffers**

( [StackBlitz](https://stackblitz.com/edit/typescript-9blquz?file=index.ts\&devtoolsheight=100))

```js
// RxJS v6+
import { interval } from 'rxjs';
import { bufferTime } from 'rxjs/operators';

//Create an observable that emits a value every 500ms
const source = interval(500);
/*
bufferTime also takes second argument, when to start the next buffer (time in ms)
for instance, if we have a bufferTime of 2 seconds but second argument (bufferCreationInterval) of 1 second:
ex. output: [0,1,2]...[1,2,3,4,5]...[3,4,5,6,7]
*/
const example = source.pipe(bufferTime(2000, 1000));
//Print values to console
const subscribe = example.subscribe(val =>
  console.log('Start Buffer Every 1s:', val)
);
```

### Additional Resources

* [bufferTime](https://rxjs.dev/api/operators/bufferTime) 📰 - Official docs
* [Time based operators comparison](/learn-rxjs/concepts/time-based-operators-comparison)

***

> 📁 Source Code: <https://github.com/ReactiveX/rxjs/blob/master/packages/rxjs/src/internal/operators/bufferTime.ts>


# bufferToggle

#### signature: `bufferToggle(openings: Observable, closingSelector: Function): Observable`

## Toggle on to catch emitted values from source, toggle off to emit buffered values as array.

### Examples

**Example 1: Toggle buffer on and off at interval**

( [StackBlitz](https://stackblitz.com/edit/typescript-xu3sq8?file=index.ts\&devtoolsheight=100) | [jsBin](http://jsbin.com/relavezugo/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/6ad3w3wf/) )

```js
// RxJS v6+
import { interval } from 'rxjs';
import { bufferToggle } from 'rxjs/operators';

//emit value every second
const sourceInterval = interval(1000);
//start first buffer after 5s, and every 5s after
const startInterval = interval(5000);
//emit value after 3s, closing corresponding buffer
const closingInterval = val => {
  console.log(`Value ${val} emitted, starting buffer! Closing in 3s!`);
  return interval(3000);
};
//every 5s a new buffer will start, collecting emitted values for 3s then emitting buffered values
const bufferToggleInterval = sourceInterval.pipe(
  bufferToggle(startInterval, closingInterval)
);
//log to console
//ex. emitted buffers [4,5,6]...[9,10,11]
const subscribe = bufferToggleInterval.subscribe(val =>
  console.log('Emitted Buffer:', val)
);
```

**Example 2: Toggle buffer on and off on mouse down/up**

( [StackBlitz](https://stackblitz.com/edit/rxjs-buffertoggle-mousemove?file=index.ts\&devtoolsheight=50) )

```js
import { fromEvent } from 'rxjs';
import { bufferToggle } from 'rxjs/operators';

fromEvent(document, 'mousemove')
  .pipe(
    bufferToggle(fromEvent(document, 'mousedown'), _ =>
      fromEvent(document, 'mouseup')
    )
  )
  .subscribe(console.log);
```

### Additional Resources

* [bufferToggle](https://rxjs.dev/api/operators/bufferToggle) 📰 - Official docs

***

> 📁 Source Code: <https://github.com/ReactiveX/rxjs/blob/master/packages/rxjs/src/internal/operators/bufferToggle.ts>


# bufferWhen

#### signature: `bufferWhen(closingSelector: function): Observable`

## Collect all values until closing selector emits, emit buffered values.

### Examples

**Example 1: Emit buffer based on interval**

( [StackBlitz](https://stackblitz.com/edit/typescript-f4a2fu?file=index.ts\&devtoolsheight=10) | [jsBin](http://jsbin.com/vugerupube/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/nr9agfuL/) )

```js
// RxJS v6+
import { interval } from 'rxjs';
import { bufferWhen } from 'rxjs/operators';

//emit value every 1 second
const oneSecondInterval = interval(1000);
//return an observable that emits value every 5 seconds
const fiveSecondInterval = () => interval(5000);
//every five seconds, emit buffered values
const bufferWhenExample = oneSecondInterval.pipe(
  bufferWhen(fiveSecondInterval)
);
//log values
//ex. output: [0,1,2,3]...[4,5,6,7,8]
const subscribe = bufferWhenExample.subscribe(val =>
  console.log('Emitted Buffer: ', val)
);
```

### Additional Resources

* [bufferWhen](https://rxjs.dev/api/operators/bufferWhen) 📰 - Official docs

***

> 📁 Source Code: <https://github.com/ReactiveX/rxjs/blob/master/packages/rxjs/src/internal/operators/bufferWhen.ts>


# concatMap

#### signature: `concatMap(project: function, resultSelector: function): Observable`

## Map values to inner observable, subscribe and emit in order.

### Why use `concatMap`?

This operator is your go-to when you have an observable that emits values and, for each of those values, you want to execute another observable sequence, ensuring they are processed in order and not concurrently. Think of it like waiting in line at a bakery: even if multiple customers arrive at once, they're served one by one. So, for instance, if you have a stream of user click events and for each click you want to initiate an HTTP request, but you need those requests to happen sequentially (one completing before the next begins), `concatMap` is what you need.

A practical scenario might be ordering saves sequentialy, without overwhelming the server with simultaneous requests.

Keep in mind that **if the inner observable takes a significant time to complete, it can lead to a backlog of outer values waiting to be processed**. In such cases, it may seem as if your application is lagging or stuck, when in reality, `concatMap` is diligently processing each value in order. For scenarios where you'd prefer to handle the most recent value and discard previous ones, consider using [`switchMap`](/learn-rxjs/operators/transformation/switchmap) instead.

Lastly, if you're not concerned about the order of processing and just want everything to execute as it arrives, [`mergeMap`](/learn-rxjs/operators/transformation/mergemap) might be the better choice.

### Examples

**Example 1: Demonstrating the difference between `concatMap` and** [**`mergeMap`**](/learn-rxjs/operators/transformation/mergemap)

( [StackBlitz](https://stackblitz.com/edit/typescript-pkyxa1?file=index.ts\&devtoolsheight=100) )

💡 Note the difference between `concatMap` and [`mergeMap`](/learn-rxjs/operators/transformation/mergemap). Because `concatMap` does not subscribe to the next observable until the previous completes, the value from the source delayed by 2000ms will be emitted first. Contrast this with [`mergeMap`](/learn-rxjs/operators/transformation/mergemap) which subscribes immediately to inner observables, the observable with the lesser delay (1000ms) will emit, followed by the observable which takes 2000ms to complete.

```js
// RxJS v6+
import { of } from 'rxjs';
import { concatMap, delay, mergeMap } from 'rxjs/operators';

//emit delay value
const source = of(2000, 1000);
// map value from source into inner observable, when complete emit result and move to next
const example = source.pipe(
  concatMap(val => of(`Delayed by: ${val}ms`).pipe(delay(val)))
);
//output: With concatMap: Delayed by: 2000ms, With concatMap: Delayed by: 1000ms
const subscribe = example.subscribe(val =>
  console.log(`With concatMap: ${val}`)
);

// showing the difference between concatMap and mergeMap
const mergeMapExample = source
  .pipe(
    // just so we can log this after the first example has run
    delay(5000),
    mergeMap(val => of(`Delayed by: ${val}ms`).pipe(delay(val)))
  )
  .subscribe(val => console.log(`With mergeMap: ${val}`));
```

**Example 2: Map to promise**

( [StackBlitz](https://stackblitz.com/edit/typescript-rv9byk?file=index.ts\&devtoolsheight=100) | [jsBin](http://jsbin.com/celixodeba/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/Lym33L97//) )

```js
// RxJS v6+
import { of } from 'rxjs';
import { concatMap } from 'rxjs/operators';

//emit 'Hello' and 'Goodbye'
const source = of('Hello', 'Goodbye');
//example with promise
const examplePromise = val => new Promise(resolve => resolve(`${val} World!`));
// map value from source into inner observable, when complete emit result and move to next
const example = source.pipe(concatMap(val => examplePromise(val)));
//output: 'Example w/ Promise: 'Hello World', Example w/ Promise: 'Goodbye World'
const subscribe = example.subscribe(val =>
  console.log('Example w/ Promise:', val)
);
```

**Example 3: Supplying a projection function**

( [StackBlitz](https://stackblitz.com/edit/typescript-2elzt7?file=index.ts\&devtoolsheight=100) | [jsBin](http://jsbin.com/vihacewozo/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/5sr5zzgy/) )

```js
// RxJS v6+
import { of } from 'rxjs';
import { concatMap } from 'rxjs/operators';

//emit 'Hello' and 'Goodbye'
const source = of('Hello', 'Goodbye');
//example with promise
const examplePromise = val => new Promise(resolve => resolve(`${val} World!`));
//result of first param passed to second param selector function before being  returned
const example = source.pipe(
  concatMap(
    val => examplePromise(val),
    result => `${result} w/ selector!`
  )
);
//output: 'Example w/ Selector: 'Hello w/ Selector', Example w/ Selector: 'Goodbye w/ Selector'
const subscribe = example.subscribe(val =>
  console.log('Example w/ Selector:', val)
);
```

### Additional Resources

* [concatMap](https://rxjs.dev/api/operators/concatMap) 📰 - Official docs
* [Use RxJS concatMap to map and concat higher order observables](https://egghead.io/lessons/rxjs-use-rxjs-concatmap-to-map-and-concat-high-order-observables?course=use-higher-order-observables-in-rxjs-effectively) 🎥 💵 - André Staltz

***

> 📁 Source Code: <https://github.com/ReactiveX/rxjs/blob/master/packages/rxjs/src/internal/operators/concatMap.ts>


# concatMapTo

#### signature: `concatMapTo(observable: Observable, resultSelector: function): Observable`

## Subscribe to provided observable when previous completes, emit values.

### Examples

**Example 1: Map to basic observable (simulating request)**

( [StackBlitz](https://stackblitz.com/edit/typescript-fkkh6c?file=index.ts\&devtoolsheight=50) )

```js
// RxJS v6+
import { of, interval } from 'rxjs';
import { concatMapTo, delay, take } from 'rxjs/operators';

//emit value every 2 seconds
const sampleInterval = interval(500).pipe(take(5));
const fakeRequest = of('Network request complete').pipe(delay(3000));
//wait for first to complete before next is subscribed
const example = sampleInterval.pipe(concatMapTo(fakeRequest));
//result
//output: Network request complete...3s...Network request complete'
const subscribe = example.subscribe(val => console.log(val));
```

**Example 2: Using projection with `concatMap`**

( [StackBlitz](https://stackblitz.com/edit/typescript-8kcfm1?file=index.ts\&devtoolsheight=100) | [jsBin](http://jsbin.com/fogefebisu/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/s19wtscb/) )

```js
// RxJS v6+
import { interval } from 'rxjs';
import { concatMapTo, take } from 'rxjs/operators';
//emit value every 2 seconds
const interval$ = interval(2000);
//emit value every second for 5 seconds
const source = interval(1000).pipe(take(5));
/*
  ***Be Careful***: In situations like this where the source emits at a faster pace
  than the inner observable completes, memory issues can arise.
  (interval emits every 1 second, basicTimer completes every 5)
*/
// basicTimer will complete after 5 seconds, emitting 0,1,2,3,4
const example = interval$.pipe(
  concatMapTo(
    source,
    (firstInterval, secondInterval) => `${firstInterval} ${secondInterval}`
  )
);
/*
  output: 0 0
          0 1
          0 2
          0 3
          0 4
          1 0
          1 1
          continued...

*/
const subscribe = example.subscribe(val => console.log(val));
```

### Additional Resources

* [concatMapTo](https://rxjs.dev/api/operators/concatMapTo) 📰 - Official docs

***

> 📁 Source Code: <https://github.com/ReactiveX/rxjs/blob/master/packages/rxjs/src/internal/operators/concatMapTo.ts>


# exhaustMap

#### signature: `exhaustMap(project: function, resultSelector: function): Observable`

## Map to inner observable, ignore other values until that observable completes.

### Why use `exhaustMap`?

Imagine you're at a coffee shop where each customer is allowed to place only one order at a time and must wait until that order is fully prepared before making another. If they try to order again while their coffee is still brewing, the barista simply ignores them. That's the essence of `exhaustMap`.

This operator is perfect for handling events that might be triggered multiple times in rapid succession but where only the initial trigger should be acted upon until it completes. A prime example would be ignoring clicks where a user might impatiently tap a 'Submit' button multiple times. Instead of sending multiple network requests, you'd ideally only want the first click to initiate the action and ignore subsequent clicks until the request is done.

Take note that **`exhaustMap` will ignore source values while the previous inner observable is still active**. This means that if the inner observable hasn't completed, any new values emitted from the source will be discarded without any mapping.

If you want to handle every single event, even if previous ones haven't completed, other operators like [`switchMap`](/learn-rxjs/operators/transformation/switchmap) or [`mergeMap`](/learn-rxjs/operators/transformation/mergemap) might be more appropriate. But when ensuring one task is exhausted before moving to the next, `exhaustMap` is your go-to choice.

### Examples

**Example 1: exhaustMap with interval**

( [Stackblitz](https://stackblitz.com/edit/typescript-3qydhn?file=index.ts\&devtoolsheight=100) | [jsBin](http://jsbin.com/woposeqobo/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/9ovzapp9/) )

```js
// RxJS v6+
import { interval, merge, of } from 'rxjs';
import { delay, take, exhaustMap } from 'rxjs/operators';

const sourceInterval = interval(1000);
const delayedInterval = sourceInterval.pipe(delay(10), take(4));

const exhaustSub = merge(
  // delay 10ms, then start interval emitting 4 values
  delayedInterval,
  // emit immediately
  of(true)
)
  .pipe(exhaustMap(_ => sourceInterval.pipe(take(5))))
  /*
   *  The first emitted value (of(true)) will be mapped
   *  to an interval observable emitting 1 value every
   *  second, completing after 5.
   *  Because the emissions from the delayed interval
   *  fall while this observable is still active they will be ignored.
   *
   *  Contrast this with concatMap which would queue,
   *  switchMap which would switch to a new inner observable each emission,
   *  and mergeMap which would maintain a new subscription for each emitted value.
   */
  // output: 0, 1, 2, 3, 4
  .subscribe(val => console.log(val));
```

**Example 2: Another exhaustMap with interval**

( [Stackblitz](https://stackblitz.com/edit/typescript-vxussb?file=index.ts\&devtoolsheight=100) | [jsBin](http://jsbin.com/fizuduzuti/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/5ck8yg5k/3/) )

```js
// RxJS v6+
import { interval } from 'rxjs';
import { exhaustMap, tap, take } from 'rxjs/operators';

const firstInterval = interval(1000).pipe(take(10));
const secondInterval = interval(1000).pipe(take(2));

const exhaustSub = firstInterval
  .pipe(
    exhaustMap(f => {
      console.log(`Emission Corrected of first interval: ${f}`);
      return secondInterval;
    })
  )
  /*
                When we subscribed to the first interval, it starts to emit a values (starting 0).
                This value is mapped to the second interval which then begins to emit (starting 0).  
                While the second interval is active, values from the first interval are ignored.
                We can see this when firstInterval emits number 3,6, and so on...

                  Output:
                  Emission of first interval: 0
                  0
                  1
                  Emission of first interval: 3
                  0
                  1
                  Emission of first interval: 6
                  0
                  1
                  Emission of first interval: 9
                  0
                  1
              */
  .subscribe(s => console.log(s));
```

### Related Recipes

* [Swipe To Refresh](/learn-rxjs/recipes/swipe-to-refresh)

### Outside Examples

**`exhaustMap` for login effect in** [**@ngrx example app**](https://github.com/ngrx/platform/tree/a9e522953832b09bb329bac4524637bc608c450a/example-app)

( [Source](https://github.com/ngrx/platform/blob/a9e522953832b09bb329bac4524637bc608c450a/example-app/app/auth/effects/auth.effects.ts#L18-L30) )

```js
@Effect()
  login$ = this.actions$.pipe(
    ofType(AuthActionTypes.Login),
    map((action: Login) => action.payload),
    exhaustMap((auth: Authenticate) =>
      this.authService
        .login(auth)
        .pipe(
          map(user => new LoginSuccess({ user })),
          catchError(error => of(new LoginFailure(error)))
        )
    )
  );
```

### Additional Resources

* [exhaustMap](https://rxjs.dev/api/operators/exhaustMap) 📰 - Official docs

***

> 📁 Source Code: <https://github.com/ReactiveX/rxjs/blob/master/packages/rxjs/src/internal/operators/exhaustMap.ts>


# expand

#### signature: `expand(project: function, concurrent: number, scheduler: Scheduler): Observable`

## Recursively call provided function.

### Examples

**Example 1: Add one for each invocation**

( [StackBlitz](https://stackblitz.com/edit/typescript-ntgecj?file=index.ts\&devtoolsheight=100) | [jsBin](http://jsbin.com/fuxocepazi/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/nu4apbLt/) )

```js
// RxJS v6+
import { interval, of } from 'rxjs';
import { expand, take } from 'rxjs/operators';

//emit 2
const source = of(2);
const example = source.pipe(
  //recursively call supplied function
  expand(val => {
    //2,3,4,5,6
    console.log(`Passed value: ${val}`);
    //3,4,5,6
    return of(1 + val);
  }),
  //call 5 times
  take(5)
);
/*
	"RESULT: 2"
	"Passed value: 2"
	"RESULT: 3"
	"Passed value: 3"
	"RESULT: 4"
	"Passed value: 4"
	"RESULT: 5"
	"Passed value: 5"
	"RESULT: 6"
	"Passed value: 6"
*/
//output: 2,3,4,5,6
const subscribe = example.subscribe(val => console.log(`RESULT: ${val}`));
```

### Related Recipes

* [Game Loop](/learn-rxjs/recipes/gameloop)

### Additional Resources

* [expand](https://rxjs.dev/api/operators/expand) 📰 - Official docs

***

> 📁 Source Code: <https://github.com/ReactiveX/rxjs/blob/master/packages/rxjs/src/internal/operators/expand.ts>


# groupBy

#### signature: `groupBy(keySelector: Function, elementSelector: Function): Observable`

## Group into observables based on provided value.

### Examples

**Example 1: Group by property**

( [StackBlitz](https://stackblitz.com/edit/typescript-dozkcg?file=index.ts\&devtoolsheight=100) | [jsBin](http://jsbin.com/buworowuye/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/utncxxvf/) )

```js
// RxJS v6+
import { from } from 'rxjs';
import { groupBy, mergeMap, toArray } from 'rxjs/operators';

const people = [
  { name: 'Sue', age: 25 },
  { name: 'Joe', age: 30 },
  { name: 'Frank', age: 25 },
  { name: 'Sarah', age: 35 }
];
//emit each person
const source = from(people);
//group by age
const example = source.pipe(
  groupBy(person => person.age),
  // return each item in group as array
  mergeMap(group => group.pipe(toArray()))
);
/*
  output:
  [{age: 25, name: "Sue"},{age: 25, name: "Frank"}]
  [{age: 30, name: "Joe"}]
  [{age: 35, name: "Sarah"}]
*/
const subscribe = example.subscribe(val => console.log(val));
```

**Example 2: Group by into key - values**

( [StackBlitz](https://stackblitz.com/edit/rxjs-groupby-key-vals?file=index.ts\&devtoolsheight=100) )

```js
// RxJS v6+
import { from, of, zip } from 'rxjs';
import { groupBy, mergeMap, toArray } from 'rxjs/operators';

const people = [
  { name: 'Sue', age: 25 },
  { name: 'Joe', age: 30 },
  { name: 'Frank', age: 25 },
  { name: 'Sarah', age: 35 }
];

from(people)
  .pipe(
    groupBy(
      person => person.age,
      p => p.name
    ),
    mergeMap(group => zip(of(group.key), group.pipe(toArray())))
  )
  .subscribe(console.log);

/*
  output:
  [25, ["Sue", "Frank"]]
  [30, ["Joe"]]
  [35, ["Sarah"]]
*/
```

### Additional Resources

* [groupBy](https://rxjs.dev/api/operators/groupBy) 📰 - Official docs
* [Group higher order observables with RxJS groupBy](https://egghead.io/lessons/rxjs-group-higher-order-observables-with-rxjs-groupby?course=use-higher-order-observables-in-rxjs-effectively) 🎥 💵 - André Staltz
* [Use groupBy in real RxJS applications](https://egghead.io/lessons/rxjs-use-groupby-in-real-rxjs-applications?course=use-higher-order-observables-in-rxjs-effectively) 🎥 💵 - André Staltz

***

> 📁 Source Code: <https://github.com/ReactiveX/rxjs/blob/master/packages/rxjs/src/internal/operators/groupBy.ts>


# map

## signature: `map(project: (value: T, index: number) => R): Observable<R>`

### Apply projection with each value from source.

{% hint style="info" %}
New to transformation operators? Check out the article [Get started transforming streams with map, pluck, and mapTo](/learn-rxjs/concepts/get-started-transforming)!
{% endhint %}

***

💡 Similar to the well-known Array.prototype.map, this is the operator you'll use most often to transform values in your streams!

💡 Need to extract a single property from an object? Before RxJS v7, you might have used `pluck`, but now `map` with destructuring or property access is the recommended approach.

💡 If your transformation function returns an Observable (like an HTTP call), you don't want `map` – you want one of the flattening operators: `mergeMap`, `switchMap`, `concatMap`, or `exhaustMap`.

💡 The `map` operator applies to each value individually. If you need to transform or combine multiple values together, look at operators like `scan`, `reduce`, or `combineLatest`.

***

### Why use map?

`map` is your go-to operator for transforming data as it flows through your observable streams. Think of it as a factory assembly line where each item gets modified before moving along. Just as a stamping machine presses a logo onto every product passing through, `map` applies your transformation function to every value that comes down the stream.

This operator truly shines when you need to reshape data to fit your application's needs. Imagine you're building a search feature for a shopping site. Your API returns complex product objects with dozens of fields – inventory counts, warehouse locations, internal IDs, and more – but your UI only needs the product name, price, and image URL. Rather than lugging around all that extra data through your application, you use `map` right after the HTTP call to [extract just what you need](#example-3-mapping-api-response-to-ui-model). This keeps your data flow clean and your components focused.

One of the most common patterns you'll encounter is using `map` to [extract properties from objects](#example-2-map-to-single-property) or responses. Whether it's grabbing the `data` property from an API response wrapper, pulling user IDs from a collection of user objects, or transforming form values into the shape your backend expects, `map` handles these everyday transformation needs. It's also perfect for [simple calculations](#example-5-calculations-and-formatting) – adding tax to prices, converting timestamps to formatted dates, or transforming coordinates for a mapping library.

What makes `map` particularly powerful is its predictability and simplicity. Unlike operators that manage multiple emissions or timing concerns, `map` has a straightforward one-to-one relationship: one input value produces one output value, synchronously. This makes it easy to reason about and debug. If a value goes in, a transformed value comes out immediately, no subscriptions required, no async complexity.

`map` is equally useful for transforming events into data you actually care about. When working with DOM events, you rarely need the entire event object – just specific properties like [mouse coordinates](#example-4-transform-dom-events) or keyboard input values. `map` lets you cleanly extract exactly what matters.

A critical point to remember: `map` is for *synchronous* transformations. If your transformation function needs to call an API, query a database, or perform any asynchronous operation that returns an Observable, `map` is the wrong choice. When you map to an Observable, you create a "higher-order Observable" (an Observable of Observables), which isn't what you want. For those scenarios, reach for `mergeMap`, `switchMap`, `concatMap`, or `exhaustMap` – the flattening operators that handle inner Observables.

In essence, whenever you find yourself thinking "I need to transform each value in this stream," `map` should be your first instinct. It's the Swiss Army knife of RxJS – simple, reliable, and perfect for the vast majority of transformation tasks you'll encounter in reactive programming.

***

## Examples

### Example 1: Add 10 to each number

( [StackBlitz](https://stackblitz.com/edit/typescript-a7bnxb?file=index.ts\&devtoolsheight=100) )

```javascript
// RxJS v6+
import { from } from 'rxjs';
import { map } from 'rxjs/operators';

//emit (1,2,3,4,5)
const source = from([1, 2, 3, 4, 5]);
//add 10 to each value
const example = source.pipe(map(val => val + 10));
//output: 11,12,13,14,15
const subscribe = example.subscribe(val => console.log(val));
```

### Example 2: Map to single property

( [StackBlitz](https://stackblitz.com/edit/typescript-qgpnju?file=index.ts\&devtoolsheight=100) )

```javascript
// RxJS v6+
import { from } from 'rxjs';
import { map } from 'rxjs/operators';

//emit ({name: 'Joe', age: 30}, {name: 'Frank', age: 20},{name: 'Ryan', age: 50})
const source = from([
  { name: 'Joe', age: 30 },
  { name: 'Frank', age: 20 },
  { name: 'Ryan', age: 50 }
]);
//extract each person's name using destructuring
const example = source.pipe(map(({ name }) => name));
//output: "Joe","Frank","Ryan"
const subscribe = example.subscribe(val => console.log(val));
```

### Example 3: Mapping API Response to UI Model

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

```javascript
// RxJS v6+
import { of } from 'rxjs';
import { map } from 'rxjs/operators';

// Simulate an API response with extra metadata
const apiResponse = of({
  status: 'success',
  timestamp: 1634567890,
  data: {
    id: 123,
    firstName: 'Jane',
    lastName: 'Doe',
    email: 'jane@example.com',
    internalFields: { /* ... */ }
  }
});

// Extract and reshape just what the UI needs
const uiModel = apiResponse.pipe(
  map(response => ({
    fullName: `${response.data.firstName} ${response.data.lastName}`,
    email: response.data.email,
    id: response.data.id
  }))
);

// output: { fullName: 'Jane Doe', email: 'jane@example.com', id: 123 }
const subscribe = uiModel.subscribe(val => console.log(val));
```

### Example 4: Transform DOM Events

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

```javascript
// RxJS v6+
import { fromEvent } from 'rxjs';
import { map } from 'rxjs/operators';

// Track mouse position from click events
const clicks = fromEvent(document, 'click');

const positions = clicks.pipe(
  map((event: MouseEvent) => ({
    x: event.clientX,
    y: event.clientY,
    timestamp: Date.now()
  }))
);

// output: { x: 234, y: 567, timestamp: 1634567891234 }
positions.subscribe(pos => console.log('Click position:', pos));
```

### Example 5: Calculations and Formatting

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

```javascript
// RxJS v6+
import { from } from 'rxjs';
import { map } from 'rxjs/operators';

// Shopping cart items
const cartItems = from([
  { name: 'Laptop', price: 999.99, quantity: 1 },
  { name: 'Mouse', price: 29.99, quantity: 2 },
  { name: 'Keyboard', price: 79.99, quantity: 1 }
]);

// Calculate total and format for display
const itemsWithTotal = cartItems.pipe(
  map(item => ({
    ...item,
    total: item.price * item.quantity,
    displayPrice: `$${(item.price * item.quantity).toFixed(2)}`
  }))
);

/* output: 
  { name: 'Laptop', price: 999.99, quantity: 1, total: 999.99, displayPrice: '$999.99' }
  { name: 'Mouse', price: 29.99, quantity: 2, total: 59.98, displayPrice: '$59.98' }
  { name: 'Keyboard', price: 79.99, quantity: 1, total: 79.99, displayPrice: '$79.99' }
*/
const subscribe = itemsWithTotal.subscribe(item => console.log(item));
```

***

### Related Recipes

* [Alphabet Invasion Game](https://www.learnrxjs.io/learn-rxjs/recipes/alphabet-invasion-game)
* [Battleship Game](https://www.learnrxjs.io/learn-rxjs/recipes/battleship-game)
* [Catch The Dot Game](https://www.learnrxjs.io/learn-rxjs/recipes/catch-the-dot-game)
* [Save Indicator](https://www.learnrxjs.io/learn-rxjs/recipes/save-indicator)
* [Smart Counter](https://www.learnrxjs.io/learn-rxjs/recipes/smartcounter)
* [Space Invaders Game](https://www.learnrxjs.io/learn-rxjs/recipes/space-invaders-game)
* [Stop Watch](https://www.learnrxjs.io/learn-rxjs/recipes/stop-watch)
* [Swipe To Refresh](https://www.learnrxjs.io/learn-rxjs/recipes/swipe-to-refresh)
* [Type Ahead](https://www.learnrxjs.io/learn-rxjs/recipes/type-ahead)

***

### Additional Resources

* [map](https://rxjs.dev/api/operators/map) 📰 - Official docs
* [map vs flatMap](https://egghead.io/lessons/rxjs-rxjs-map-vs-flatmap) 🎥 - Ben Lesh
* [Transformation operator: map and mapTo](https://egghead.io/lessons/rxjs-transformation-operator-map-and-mapto?course=rxjs-beyond-the-basics-operators-in-depth) 🎥 💵 - André Staltz

***

📁 **Source Code:** <https://github.com/ReactiveX/rxjs/blob/master/packages/rxjs/src/internal/operators/map.ts>


# mapTo

#### signature: `mapTo(value: any): Observable`

## Map emissions to constant value.

{% hint style="info" %}
New to transformation operators? Check out the article [Get started transforming streams with map, pluck, and mapTo](/learn-rxjs/concepts/get-started-transforming)!
{% endhint %}

### Examples

**Example 1: Map every emission to string**

( [StackBlitz](https://stackblitz.com/edit/typescript-fipd7a?file=index.ts\&devtoolsheight=100) | [jsBin](http://jsbin.com/qujolenili/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/4ojq56ng/) )

```js
// RxJS v6+
import { interval } from 'rxjs';
import { mapTo } from 'rxjs/operators';

//emit value every two seconds
const source = interval(2000);
//map all emissions to one value
const example = source.pipe(mapTo('HELLO WORLD!'));
//output: 'HELLO WORLD!'...'HELLO WORLD!'...'HELLO WORLD!'...
const subscribe = example.subscribe(val => console.log(val));
```

**Example 2: Mapping clicks to string**

( [StackBlitz](https://stackblitz.com/edit/typescript-btghci?file=index.ts\&devtoolsheight=100) | [jsBin](http://jsbin.com/xaheciwara/1/edit?js,console,output) | [jsFiddle](https://jsfiddle.net/btroncone/52fqL4nn/) )

```js
// RxJS v6+
import { fromEvent } from 'rxjs';
import { mapTo } from 'rxjs/operators';

//emit every click on document
const source = fromEvent(document, 'click');
//map all emissions to one value
const example = source.pipe(mapTo('GOODBYE WORLD!'));
//output: (click)'GOODBYE WORLD!'...
const subscribe = example.subscribe(val => console.log(val));
```

### Related Recipes

* [HTTP Polling](/learn-rxjs/recipes/http-polling)
* [Save Indicator](/learn-rxjs/recipes/save-indicator)
* [Smart Counter](/learn-rxjs/recipes/smartcounter)
* [Stop Watch](/learn-rxjs/recipes/stop-watch)

### Additional Resources

* [mapTo](https://rxjs.dev/api/operators/mapTo) 📰 - Official docs
* [Changing behavior with mapTo](https://egghead.io/lessons/rxjs-changing-behavior-with-mapto?course=step-by-step-async-javascript-with-rxjs) 🎥 💵 - John Linquist
* [Transformation operator: map and mapTo](https://egghead.io/lessons/rxjs-transformation-operator-map-and-mapto?course=rxjs-beyond-the-basics-operators-in-depth) 🎥 💵 - André Staltz

***

> 📁 Source Code: <https://github.com/ReactiveX/rxjs/blob/master/packages/rxjs/src/internal/operators/mapTo.ts>


# mergeMap / flatMap

#### signature: `mergeMap(project: function: Observable, resultSelector: function: any, concurrent: number): Observable`

## Map to observable, emit values.

***

💡 flatMap is an alias for mergeMap!

💡 If only one inner subscription should be active at a time, try [`switchMap`](/learn-rxjs/operators/transformation/switchmap)!

💡 If the order of emission and subscription of inner observables is important, try [`concatMap`](/learn-rxjs/operators/transformation/concatmap)!

***

### Why use `mergeMap`?

This operator is best used when you wish to flatten an inner observable but want to manually control the number of inner subscriptions.

For instance, when using [`switchMap`](/learn-rxjs/operators/transformation/switchmap) each inner subscription is completed when the source emits, allowing only one active inner subscription. In contrast, `mergeMap` allows for multiple inner subscriptions to be active at a time. Because of this, one of the most common use-case for `mergeMap` is requests that should not be canceled, think writes rather than reads. Note that if order must be maintained [`concatMap`](/learn-rxjs/operators/transformation/concatmap) is a better option.

Be aware that because `mergeMap` maintains multiple active inner subscriptions at once it's possible to create a memory leak through long-lived inner subscriptions. A basic example would be if you were mapping to an observable with an inner timer, or a stream of dom events. In these cases, if you still wish to utilize `mergeMap` you may want to take advantage of another operator to manage the completion of the inner subscription, think [`take`](/learn-rxjs/operators/filtering/take) or [`takeUntil`](/learn-rxjs/operators/filtering/takeuntil). You can also limit the number of active inner subscriptions at a time with the `concurrent` parameter, seen in [example 5](#example-5-mergemap-with-concurrent-value).

### Examples

**Example 1: mergeMap simulating save of click locations**

( [StackBlitz](https://stackblitz.com/edit/rxjs-xfwdnl?file=index.ts\&devtoolsheight=60) )

```js
// RxJS v6+
import { fromEvent, of } from 'rxjs';
import { mergeMap, delay } from 'rxjs/operators';

// faking network request for save
const saveLocation = location => {
  return of(location).pipe(delay(500));
};
// streams
const click$ = fromEvent(document, 'click');

click$
  .pipe(
    mergeMap((e: MouseEvent) => {
      return saveLocation({
        x: e.clientX,
        y: e.clientY,
        timestamp: Date.now()
      });
    })
  )
  // Saved! {x: 98, y: 170, ...}
  .subscribe(r => console.log('Saved!', r));
```

**Example 2: mergeMap with ajax observable**

( [StackBlitz](https://stackblitz.com/edit/rxjs-wixf2a?file=index.ts\&devtoolsheight=60) )

```js
// RxJS v6+
import { fromEvent } from 'rxjs';
import { ajax } from 'rxjs/ajax';
import { mergeMap } from 'rxjs/operators';

// free api url
const API_URL = 'https://jsonplaceholder.typicode.com/todos/1';

// streams
const click$ = fromEvent(document, 'click');

click$
  .pipe(
    /*
     * Using mergeMap for example, but generally for GET requests
     * you will prefer switchMap.
     * Also, if you do not need the parameter like
     * below you could use mergeMapTo instead.
     * ex. mergeMapTo(ajax.getJSON(API_URL))
     */
    mergeMap(() => ajax.getJSON(API_URL))
  )
  // { userId: 1, id: 1, ...}
  .subscribe(console.log);
```

**Example 3: mergeMap with promise (could also use** [**from**](/learn-rxjs/operators/creation/from) **to convert to observable)**

( [StackBlitz](https://stackblitz.com/edit/typescript-pnnsrq?file=index.ts\&devtoolsheight=100) )

```js
// RxJS v6+
import { of } from 'rxjs';
import { mergeMap } from 'rxjs/operators';

// helper to create promise
const myPromise = val =>
  new Promise(resolve => resolve(`${val} World From Promise!`));

// emit 'Hello'
const source$ = of('Hello');

// map to promise and emit result
source$
  .pipe(mergeMap(val => myPromise(val)))
  // output: 'Hello World From Promise'
  .subscribe(val => console.log(val));
```

**Example 4: mergeMap with `resultSelector`**

( [StackBlitz](https://stackblitz.com/edit/typescript-9p6ws7?file=index.ts\&devtoolsheight=100) )

```js
// RxJS v6+
import { of } from 'rxjs';
import { mergeMap } from 'rxjs/operators';

// helper to create promise
const myPromise = val =>
  new Promise(resolve => resolve(`${val} World From Promise!`));

// emit 'Hello'
const source$ = of('Hello');

source$
  .pipe(
    mergeMap(
      val => myPromise(val),
      /*
      you can also supply a second argument which receives the source value and emitted
      value of inner observable or promise
    */
      (valueFromSource, valueFromPromise) => {
        return `Source: ${valueFromSource}, Promise: ${valueFromPromise}`;
      }
    )
  )
  // output: "Source: Hello, Promise: Hello World From Promise!"
  .subscribe(val => console.log(val));
```

**Example 5: mergeMap with concurrent value**

( [StackBlitz](https://stackblitz.com/edit/typescript-r3gcr4?file=index.ts\&devtoolsheight=100) )

```js
// RxJS v6+
import { interval } from 'rxjs';
import { mergeMap, take } from 'rxjs/operators';

// emit value every 1s
const source$ = interval(1000);

source$
  .pipe(
    mergeMap(
      // project
      val => interval(5000).pipe(take(2)),
      // resultSelector
      (oVal, iVal, oIndex, iIndex) => [oIndex, oVal, iIndex, iVal],
      // concurrent
      2
    )
  )
  /*
		Output:
		[0, 0, 0, 0] <--1st inner observable
		[1, 1, 0, 0] <--2nd inner observable
		[0, 0, 1, 1] <--1st inner observable
		[1, 1, 1, 1] <--2nd inner observable
		[2, 2, 0, 0] <--3rd inner observable
		[3, 3, 0, 0] <--4th inner observable
*/
  .subscribe(val => console.log(val));
```

### Related Recipes

* [Breakout Game](/learn-rxjs/recipes/breakout-game)
* [HTTP Polling](/learn-rxjs/recipes/http-polling)
* [Save Indicator](/learn-rxjs/recipes/save-indicator)
* [Swipe To Refresh](/learn-rxjs/recipes/swipe-to-refresh)

### Additional Resources

* [mergeMap](https://rxjs.dev/api/operators/mergeMap) 📰 - Official docs
* [map vs flatMap](https://egghead.io/lessons/rxjs-rxjs-map-vs-flatmap) 🎥 💵 - Ben Lesh
* [Async requests and responses in RxJS](https://egghead.io/lessons/rxjs-04-reactive-programming-async-requests-and-responses-in-rxjs) 🎥 💵 - André Staltz
* [Use RxJS mergeMap to map and merge higher order observables](https://egghead.io/lessons/rxjs-use-rxjs-mergemap-to-map-and-merge-high-order-observables?course=use-higher-order-observables-in-rxjs-effectively) 🎥 💵 - André Staltz
* [Use RxJS mergeMap for fine grain custom behavior](https://egghead.io/lessons/rxjs-use-rxjs-mergemap-for-fine-grain-custom-behavior?course=use-higher-order-observables-in-rxjs-effectively) 🎥 💵 - André Staltz

***

> 📁 Source Code: <https://github.com/ReactiveX/rxjs/blob/master/packages/rxjs/src/internal/operators/mergeMap.ts>


# mergeScan

#### signature: `mergeScan(accumulator: (acc, value, index: number) => ObservableInput, seed, concurrent: number = Number.POSITIVE_INFINITY): OperatorFunction`

## Accumulate value over time via merged observables.

### Examples

**Example 1: Accumulate total duration mouse held down over time**

( [StackBlitz](https://stackblitz.com/edit/typescript-gzaak8?file=index.ts\&devtoolsheight=50) )

```js
// RxJS v6+
import { fromEvent, interval } from 'rxjs';
import { mergeScan, take, takeUntil, map, scan } from 'rxjs/operators';

// reference
const durationElem = document.getElementById('duration');

// streams
const mouseDown$ = fromEvent(document, 'mousedown');
const mouseUp$ = fromEvent(document, 'mouseup');

// accumulate time mouse held down over time
mouseDown$
  .pipe(
    mergeScan((acc, curr) => {
      return interval(1000).pipe(
        scan((a, _) => ++a, 0),
        map((val: any) => val + acc),
        takeUntil(mouseUp$)
      );
    }, 0)
    // output: 1s...2s...3s...4s...
  )
  .subscribe(val => (durationElem.innerHTML = `${val}s`));
```

### Additional Resources

* [pluck](https://rxjs-dev.firebaseapp.com/api/operators/mergeScan) 📰 - Official docs

***

> 📁 Source Code: <https://github.com/ReactiveX/rxjs/blob/master/packages/rxjs/src/internal/operators/mergeScan.ts>


# partition

#### signature: `partition(predicate: function: boolean, thisArg: any): [Observable, Observable]`

## Split one observable into two based on provided predicate.

### Examples

**Example 1: Split even and odd numbers**

( [StackBlitz](https://stackblitz.com/edit/typescript-gr3ljs?file=index.ts\&devtoolsheight=100) | [jsBin](http://jsbin.com/hipehexaku/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/q0xo7gvv/) )

```js
// RxJS v6+
import { from, merge } from 'rxjs';
import { partition, map } from 'rxjs/operators';

const source = from([1, 2, 3, 4, 5, 6]);
//first value is true, second false
const [evens, odds] = source.pipe(partition(val => val % 2 === 0));
/*
  Output:
  "Even: 2"
  "Even: 4"
  "Even: 6"
  "Odd: 1"
  "Odd: 3"
  "Odd: 5"
*/
const subscribe = merge(
  evens.pipe(map(val => `Even: ${val}`)),
  odds.pipe(map(val => `Odd: ${val}`))
).subscribe(val => console.log(val));
```

**Example 2: Split success and errors**

( [StackBlitz](https://stackblitz.com/edit/typescript-vmfvp8?file=index.ts\&devtoolsheight=100) | [jsBin](http://jsbin.com/kukuguhuri/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/fe246u5p/) )

```js
// RxJS v6+
import { merge, of, from } from 'rxjs';
import { map, partition, catchError } from 'rxjs/operators';

const source = from([1, 2, 3, 4, 5, 6]);
//if greater than 3 throw
const example = source.pipe(
  map(val => {
    if (val > 3) {
      throw `${val} greater than 3!`;
    }
    return { success: val };
  }),
  catchError(val => of({ error: val }))
);
//split on success or error
const [success, error] = example.pipe(partition(res => res.success));
/*
  Output:
  "Success! 1"
  "Success! 2"
  "Success! 3"
  "Error! 4 greater than 3!"
*/
const subscribe = merge(
  success.pipe(map(val => `Success! ${val.success}`)),
  error.pipe(map(val => `Error! ${val.error}`))
).subscribe(val => console.log(val));
```

**Example 3: (v6.5+) Partition as a static function**

( [StackBlitz](https://stackblitz.com/edit/typescript-vmfvp8?file=index.ts\&devtoolsheight=100) )

```js
// RxJS v6.5+
import { merge, of, from, partition } from 'rxjs';
import { map, catchError } from 'rxjs/operators';

const source = from([1, 2, 3, 4, 5, 6]);
//if greater than 3 throw
const example = source.pipe(
  map(val => {
    if (val > 3) {
      throw `${val} greater than 3!`;
    }
    return { success: val };
  }),
  catchError(val => of({ error: val }))
);
// split on success or error
const [success, error] = partition(example, res => res.success);
/*
  Output:
  "Success! 1"
  "Success! 2"
  "Success! 3"
  "Error! 4 greater than 3!"
*/
const subscribe = merge(
  success.pipe(map(val => `Success! ${val.success}`)),
  error.pipe(map(val => `Error! ${val.error}`))
).subscribe(val => console.log(val));
```

### Additional Resources

* [partition](https://rxjs.dev/api/operators/partition) 📰 - Official docs

***

> 📁 Source Code: <https://github.com/ReactiveX/rxjs/blob/master/src/internal/observable/partition.ts>


# pluck

#### signature: `pluck(properties: ...args): Observable`

## Select property to emit.

{% hint style="info" %}
New to transformation operators? Check out the article [Get started transforming streams with map, pluck, and mapTo](/learn-rxjs/concepts/get-started-transforming)!
{% endhint %}

### Examples

**Example 1: Pluck object property**

( [StackBlitz](https://stackblitz.com/edit/typescript-jkda4e?file=index.ts\&devtoolsheight=100) | [jsBin](http://jsbin.com/zokaxiwahe/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/58v9xq0f/) )

```js
// RxJS v6+
import { from } from 'rxjs';
import { pluck } from 'rxjs/operators';

const source = from([
  { name: 'Joe', age: 30 },
  { name: 'Sarah', age: 35 }
]);
//grab names
const example = source.pipe(pluck('name'));
//output: "Joe", "Sarah"
const subscribe = example.subscribe(val => console.log(val));
```

**Example 2: Pluck nested properties**

( [StackBlitz](https://stackblitz.com/edit/typescript-rinjzk?file=index.ts\&devtoolsheight=100) | [jsBin](http://jsbin.com/joqesidugu/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/n592m597/) )

```js
// RxJS v6+
import { from } from 'rxjs';
import { pluck } from 'rxjs/operators';

const source = from([
  { name: 'Joe', age: 30, job: { title: 'Developer', language: 'JavaScript' } },
  //will return undefined when no job is found
  { name: 'Sarah', age: 35 }
]);
//grab title property under job
const example = source.pipe(pluck('job', 'title'));
//output: "Developer" , undefined
const subscribe = example.subscribe(val => console.log(val));
```

### Related Recipes

* [Breakout Game](/learn-rxjs/recipes/breakout-game)
* [Car Racing Game](/learn-rxjs/recipes/car-racing-game)
* [Lockscreen](/learn-rxjs/recipes/lockscreen)
* [Memory Game](/learn-rxjs/recipes/memory-game)
* [Mine Sweeper Game](/learn-rxjs/recipes/mine-sweeper-game)
* [Platform Jumper Game](/learn-rxjs/recipes/platform-jumper-game)
* [Tetris Game](/learn-rxjs/recipes/tetris-game)
* [Uncover Image Game](/learn-rxjs/recipes/uncover-image-game)

### Additional Resources

* [pluck](https://rxjs.dev/api/operators/pluck) 📰 - Official docs

***

> 📁 Source Code: <https://github.com/ReactiveX/rxjs/blob/master/packages/rxjs/src/internal/operators/pluck.ts>


# reduce

#### signature: `reduce(accumulator: function, seed: any): Observable`

## Reduces the values from source observable to a single value that's emitted when the source completes.

💡 Just like [`Array.prototype.reduce()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce?v=a)

💡 If you need the current accumulated value on each emission, try [scan](/learn-rxjs/operators/transformation/scan)!

### Examples

**Example 1: Sum a stream of numbers**

( [StackBlitz](https://stackblitz.com/edit/typescript-hdsv5e?file=index.ts\&devtoolsheight=100) | [jsBin](http://jsbin.com/dakuneneho/edit?js,console) | [jsFiddle](https://jsfiddle.net/f8fw7yka/) )

```js
// RxJS v6+
import { of } from 'rxjs';
import { reduce } from 'rxjs/operators';

const source = of(1, 2, 3, 4);
const example = source.pipe(reduce((acc, val) => acc + val));
//output: Sum: 10'
const subscribe = example.subscribe(val => console.log('Sum:', val));
```

### Additional Resources

* [reduce](https://rxjs.dev/api/operators/reduce) 📰 - Official docs
* [Scan() vs reduce() | RxJS TUTORIAL](https://www.youtube.com/watch?v=myEeo2rZc3g) 🎥 - Academind

***

> 📁 Source Code: <https://github.com/ReactiveX/rxjs/blob/master/packages/rxjs/src/internal/operators/reduce.ts>


# scan

#### signature: `scan(accumulator: function, seed: any): Observable`

## Reduce over time.

***

💡 You can create [Redux](http://redux.js.org)-like state management with scan!

***

### Why use `scan`?

The key distinction of the scan operator when compared to other reduction operators is its continuous accumulation feature. With each emitted value, the accumulator function is applied, and the accumulated result is emitted instantaneously. You can remember this by the phrase "accumulate and emit on-the-go."

The scan operator is highly useful in scenarios that require real-time monitoring and processing, such as tallying scores in a game, where you want to display the updated score each time points are added. However, be cautious when using scan for cases where the *only* the final accumulated result is crucial. In those situations, the [`reduce`](/learn-rxjs/operators/transformation/reduce) operator may be more appropriate, as it emits only the final value after the source completes.

In summary, the scan operator provides a powerful and flexible means of handling continuous accumulation and emission of values, which can be especially useful in real-time monitoring and processing tasks.

### Examples

**Example 1: Sum over time**

( [StackBlitz](https://stackblitz.com/edit/typescript-ltcl9d?file=index.ts\&devtoolsheight=100) )

```js
// RxJS v6+
import { of } from 'rxjs';
import { scan } from 'rxjs/operators';

const source = of(1, 2, 3);
// basic scan example, sum over time starting with zero
const example = source.pipe(scan((acc, curr) => acc + curr, 0));
// log accumulated values
// output: 1,3,6
const subscribe = example.subscribe(val => console.log(val));
```

**Example 2: Accumulating an object**

( [StackBlitz](https://stackblitz.com/edit/typescript-vu63kz?file=index.ts\&devtoolsheight=100) | [jsBin](http://jsbin.com/fusunoguqu/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/36rbu38b/) )

```js
// RxJS v6+
import { Subject } from 'rxjs';
import { scan } from 'rxjs/operators';

const subject = new Subject();
//scan example building an object over time
const example = subject.pipe(
  scan((acc, curr) => Object.assign({}, acc, curr), {})
);
//log accumulated values
const subscribe = example.subscribe(val =>
  console.log('Accumulated object:', val)
);
//next values into subject, adding properties to object
// {name: 'Joe'}
subject.next({ name: 'Joe' });
// {name: 'Joe', age: 30}
subject.next({ age: 30 });
// {name: 'Joe', age: 30, favoriteLanguage: 'JavaScript'}
subject.next({ favoriteLanguage: 'JavaScript' });
```

**Example 3: Emitting random values from the accumulated array.**

( [StackBlitz](https://stackblitz.com/edit/typescript-lb8aw9?file=index.ts\&devtoolsheight=100) )

```js
// RxJS v6+
import { interval } from 'rxjs';
import { scan, map, distinctUntilChanged } from 'rxjs/operators';

// Accumulate values in an array, emit random values from this array.
const scanObs = interval(1000)
  .pipe(
    scan((a, c) => [...a, c], []),
    map(r => r[Math.floor(Math.random() * r.length)]),
    distinctUntilChanged()
  )
  .subscribe(console.log);
```

**Example 4: Accumulating http responses over time**

( [StackBlitz](https://stackblitz.com/edit/rxjs-scan-accumulate-request-responses?file=index.ts\&devtoolsheight=100) )

```js
// RxJS v6+
import { interval, of } from 'rxjs';
import { scan, delay, repeat, mergeMap } from 'rxjs/operators';

const fakeRequest = of('response').pipe(delay(2000));

// output:
// ['response'],
// ['response','response'],
// ['response','response','response'],
// etc...

interval(1000)
  .pipe(
    mergeMap(_ => fakeRequest),
    scan < string > ((all, current) => [...all, current], [])
  )
  .subscribe(console.log);
```

### Related Recipes

* [Alphabet Invasion Game](/learn-rxjs/recipes/alphabet-invasion-game)
* [Battleship Game](/learn-rxjs/recipes/battleship-game)
* [Breakout Game](/learn-rxjs/recipes/breakout-game)
* [Car Racing Game](/learn-rxjs/recipes/car-racing-game)
* [Catch The Dot Game](/learn-rxjs/recipes/catch-the-dot-game)
* [Click Ninja Game](/learn-rxjs/recipes/click-ninja-game)
* [Flappy Bird Game](/learn-rxjs/recipes/flappy-bird-game)
* [Matrix Digital Rain](/learn-rxjs/recipes/matrix-digital-rain)
* [Memory Game](/learn-rxjs/recipes/memory-game)
* [Platform Jumper Game](/learn-rxjs/recipes/platform-jumper-game)
* [Progress Bar](/learn-rxjs/recipes/progressbar)
* [Smart Counter](/learn-rxjs/recipes/smartcounter)
* [Space Invaders Game](/learn-rxjs/recipes/space-invaders-game)
* [Stop Watch](/learn-rxjs/recipes/stop-watch)
* [Tank Battle Game](/learn-rxjs/recipes/tank-battle-game)
* [Tetris Game](/learn-rxjs/recipes/tetris-game)
* [Uncover Image Game](/learn-rxjs/recipes/uncover-image-game)

### Additional Resources

* [scan](https://rxjs.dev/api/operators/scan) 📰 - Official docs
* [Aggregating streams with reduce and scan using RxJS](https://egghead.io/lessons/rxjs-aggregating-streams-with-reduce-and-scan-using-rxjs) 🎥 - Ben Lesh
* [Updating data with scan](https://egghead.io/lessons/rxjs-updating-data-with-scan?course=step-by-step-async-javascript-with-rxjs) 🎥 💵 - John Linquist
* [Transformation operator: scan](https://egghead.io/lessons/rxjs-transformation-operator-scan?course=rxjs-beyond-the-basics-operators-in-depth) 🎥 💵 - André Staltz

***

> 📁 Source Code: <https://github.com/ReactiveX/rxjs/blob/master/packages/rxjs/src/internal/operators/scan.ts>


# switchMap

#### signature: `switchMap(project: function: Observable, resultSelector: function(outerValue, innerValue, outerIndex, innerIndex): any): Observable`

## Map to observable, complete previous inner observable, emit values.

***

💡 If you would like more than one inner subscription to be maintained, try [`mergeMap`](/learn-rxjs/operators/transformation/mergemap)!

💡 This operator is generally considered a safer default to [`mergeMap`](/learn-rxjs/operators/transformation/mergemap)!

💡 This operator can cancel in-flight network requests!

***

### Why use `switchMap`?

The main difference between `switchMap` and other flattening operators is the cancelling effect. On each emission the previous inner observable (the result of the function you supplied) is cancelled and the new observable is subscribed. You can remember this by the phrase **switch to a new observable**.

This works perfectly for scenarios like [typeaheads](https://angular-2-training-book.rangle.io/handout/http/search_with_switchmap.html) where you are no longer concerned with the response of the previous request when a new input arrives. This also is a safe option in situations where a long lived inner observable could cause memory leaks, for instance if you used [mergeMap](/learn-rxjs/operators/transformation/mergemap) with an interval and forgot to properly dispose of inner subscriptions. Remember, `switchMap` maintains only one inner subscription at a time, this can be seen clearly in the [first example](#example-1-restart-interval-every-5-seconds).

Be careful though, you probably want to avoid `switchMap` in scenarios where every request needs to complete, think writes to a database. `switchMap` could cancel a request if the source emits quickly enough. In these scenarios [mergeMap](/learn-rxjs/operators/transformation/mergemap) is the correct option.

### Examples

**Example 1: Restart interval on every click**

( [StackBlitz](https://stackblitz.com/edit/typescript-s4pvix?file=index.ts\&devtoolsheight=100) )

```js
// RxJS v6+
import { interval, fromEvent } from 'rxjs';
import { switchMap } from 'rxjs/operators';

fromEvent(document, 'click')
  .pipe(
    // restart counter on every click
    switchMap(() => interval(1000))
  )
  .subscribe(console.log);
```

**Example 2: Countdown timer with pause and resume**

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

```js
// RxJS v6+
import { interval, fromEvent, merge, empty } from 'rxjs';
import { switchMap, scan, takeWhile, startWith, mapTo } from 'rxjs/operators';

const COUNTDOWN_SECONDS = 10;

// elem refs
const remainingLabel = document.getElementById('remaining');
const pauseButton = document.getElementById('pause');
const resumeButton = document.getElementById('resume');

// streams
const interval$ = interval(1000).pipe(mapTo(-1));
const pause$ = fromEvent(pauseButton, 'click').pipe(mapTo(false));
const resume$ = fromEvent(resumeButton, 'click').pipe(mapTo(true));

const timer$ = merge(pause$, resume$)
  .pipe(
    startWith(true),
    switchMap(val => (val ? interval$ : empty())),
    scan((acc, curr) => (curr ? curr + acc : acc), COUNTDOWN_SECONDS),
    takeWhile(v => v >= 0)
  )
  .subscribe((val: any) => (remainingLabel.innerHTML = val));
```

**Example 3: Using a `resultSelector` function**

( [StackBlitz](https://stackblitz.com/edit/typescript-bmibzi?file=index.ts\&devtoolsheight=100) )

```js
// RxJS v6+
import { timer, interval } from 'rxjs';
import { switchMap } from 'rxjs/operators';

// switch to new inner observable when source emits, emit result of project function
timer(0, 5000)
  .pipe(
    switchMap(
      _ => interval(2000),
      (outerValue, innerValue, outerIndex, innerIndex) => ({
        outerValue,
        innerValue,
        outerIndex,
        innerIndex
      })
    )
  )
  /*
	Output:
	{outerValue: 0, innerValue: 0, outerIndex: 0, innerIndex: 0}
	{outerValue: 0, innerValue: 1, outerIndex: 0, innerIndex: 1}
	{outerValue: 1, innerValue: 0, outerIndex: 1, innerIndex: 0}
	{outerValue: 1, innerValue: 1, outerIndex: 1, innerIndex: 1}
*/
  .subscribe(console.log);
```

### Related Recipes

* [Alphabet Invasion Game](/learn-rxjs/recipes/alphabet-invasion-game)
* [Battleship Game](/learn-rxjs/recipes/battleship-game)
* [Car Racing Game](/learn-rxjs/recipes/car-racing-game)
* [Catch The Dot Game](/learn-rxjs/recipes/catch-the-dot-game)
* [HTTP Polling](/learn-rxjs/recipes/http-polling)
* [Lockscreen](/learn-rxjs/recipes/lockscreen)
* [Memory Game](/learn-rxjs/recipes/memory-game)
* [Mine Sweeper Game](/learn-rxjs/recipes/mine-sweeper-game)
* [Platform Jumper Game](/learn-rxjs/recipes/platform-jumper-game)
* [Progress Bar](/learn-rxjs/recipes/progressbar)
* [Smart Counter](/learn-rxjs/recipes/smartcounter)
* [Stop Watch](/learn-rxjs/recipes/stop-watch)
* [Typeahead](/learn-rxjs/recipes/type-ahead)

### Additional Resources

* [switchMap](https://rxjs.dev/api/operators/switchMap) 📰 - Official docs
* [Avoiding switchMap-Related Bugs](https://blog.angularindepth.com/switchmap-bugs-b6de69155524) - Nicholas Jamieson
* [Starting a stream with switchMap](https://egghead.io/lessons/rxjs-starting-a-stream-with-switchmap?course=step-by-step-async-javascript-with-rxjs) 🎥 💵 - John Linquist
* [Use RxJS switchMap to map and flatten higher order observables](https://egghead.io/lessons/rxjs-use-rxjs-switchmap-to-map-and-flatten-higher-order-observables?course=use-higher-order-observables-in-rxjs-effectively) 🎥 💵 - André Staltz
* [Use switchMap as a safe default to flatten observables in RxJS](https://egghead.io/lessons/rxjs-use-switchmap-as-a-safe-default-to-flatten-observables-in-rxjs?course=use-higher-order-observables-in-rxjs-effectively) 🎥 💵 - André Staltz

***

> 📁 Source Code: <https://github.com/ReactiveX/rxjs/blob/master/packages/rxjs/src/internal/operators/switchMap.ts>


# switchMapTo

#### signature: `switchMapTo(innerObservable: Observable, resultSelector: function(outerValue, innerValue, outerIndex, innerIndex): any): Observable`

## Map to same inner observable, complete previous inner observable.

***

💡 If you need to consider the emitted value from the source, try [`switchMap`](/learn-rxjs/operators/transformation/switchmap)!

***

### Examples

**Example 1: Restart countdown on click, until countdown completes one time**

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

```js
// RxJS v6+
import { interval, fromEvent } from 'rxjs';
import {
  switchMapTo,
  scan,
  startWith,
  takeWhile,
  finalize
} from 'rxjs/operators';

const COUNTDOWN_TIME = 10;

// reference
const countdownElem = document.getElementById('countdown');

// streams
const click$ = fromEvent(document, 'click');
const countdown$ = interval(1000).pipe(
  scan((acc, _) => --acc, COUNTDOWN_TIME),
  startWith(COUNTDOWN_TIME)
);

click$
  .pipe(
    switchMapTo(countdown$),
    takeWhile(val => val >= 0),
    finalize(() => (countdownElem.innerHTML = "We're done here!"))
  )
  .subscribe((val: any) => (countdownElem.innerHTML = val));
```

### Additional Resources

* [switchMapTo](https://rxjs.dev/api/operators/switchMapTo) 📰 - Official docs

***

> 📁 Source Code: <https://github.com/ReactiveX/rxjs/blob/master/packages/rxjs/src/internal/operators/switchMapTo.ts>


# toArray

#### signature: `toArray(): OperatorFunction`

## Collects all source emissions and emits them as an array when the source completes.

### Examples

**Example 1: get values emitted by interval as an array when interval completes**

( [StackBlitz](https://stackblitz.com/edit/rxjs-toarray?file=index.ts\&devtoolsheight=100) )

```js
// RxJS v6+
import { interval } from 'rxjs';
import { toArray, take } from 'rxjs/operators';

interval(100)
  .pipe(take(10), toArray())
  .subscribe(console.log);

// output: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
```

### Related Recipes

* [Breakout Game](/learn-rxjs/recipes/breakout-game)
* [Lockscreen](/learn-rxjs/recipes/lockscreen)

### Additional Resources

* [toArray](https://rxjs.dev/api/operators/toArray) 📰 - Official docs

***

> 📁 Source Code: <https://github.com/ReactiveX/rxjs/blob/master/packages/rxjs/src/internal/operators/toArray.ts>


# window

#### signature: `window(windowBoundaries: Observable): Observable`

## Observable of values for window of time.

### Examples

**Example 1: Open window specified by inner observable**

( [StackBlitz](https://stackblitz.com/edit/typescript-avymzq?file=index.ts\&devtoolsheight=100) | [jsBin](http://jsbin.com/jituvajeri/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/rmgghg6d/) )

```js
// RxJS v6+
import { timer, interval } from 'rxjs';
import { window, scan, mergeAll } from 'rxjs/operators';

//emit immediately then every 1s
const source = timer(0, 1000);
const example = source.pipe(window(interval(3000)));
const count = example.pipe(scan((acc, curr) => acc + 1, 0));
/*
  "Window 1:"
  0
  1
  2
  "Window 2:"
  3
  4
  5
  ...
*/
const subscribe = count.subscribe(val => console.log(`Window ${val}:`));
const subscribeTwo = example
  .pipe(mergeAll())
  .subscribe(val => console.log(val));
```

### Additional Resources

* [window](https://rxjs.dev/api/operators/window) 📰 - Official docs
* [Split an RxJS observable with window](https://egghead.io/lessons/rxjs-split-an-rxjs-observable-with-window?course=use-higher-order-observables-in-rxjs-effectively) 🎥 💵 - André Staltz

***

> 📁 Source Code: <https://github.com/ReactiveX/rxjs/blob/master/packages/rxjs/src/internal/operators/window.ts>


# windowCount

#### signature: `windowCount(windowSize: number, startWindowEvery: number): Observable`

## Observable of values from source, emitted each time provided count is fulfilled.

### Examples

**Example 1: Start new window every x items emitted**

( [StackBlitz](https://stackblitz.com/edit/typescript-kcxi8y?file=index.ts\&devtoolsheight=100) | [jsBin](http://jsbin.com/nezuvacexe/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/xjgbnqp5/) )

```js
// RxJS v6+
import { interval } from 'rxjs';
import { windowCount, mergeAll, tap } from 'rxjs/operators';

//emit every 1s
const source = interval(1000);
const example = source.pipe(
  //start new window every 4 emitted values
  windowCount(4),
  tap(_ => console.log('NEW WINDOW!'))
);

const subscribeTwo = example
  .pipe(
    //window emits nested observable
    mergeAll()
    /*
            output:
            "NEW WINDOW!"
            0
            1
            2
            3
            "NEW WINDOW!"
            4
            5
            6
            7
          */
  )
  .subscribe(val => console.log(val));
```

### Additional Resources

* [windowCount](https://rxjs.dev/api/operators/windowCount) 📰 - Official docs

***

> 📁 Source Code: <https://github.com/ReactiveX/rxjs/blob/master/packages/rxjs/src/internal/operators/windowCount.ts>


# windowTime

#### signature: `windowTime(windowTimeSpan: number, windowCreationInterval: number, scheduler: Scheduler): Observable`

## Observable of values collected from source for each provided time span.

### Examples

**Example 1: Open new window every specified duration**

( [StackBlitz](https://stackblitz.com/edit/typescript-hkrjsc?file=index.ts\&devtoolsheight=100) | [jsBin](http://jsbin.com/mifayacoqo/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/g04b3qeb/) )

```js
// RxJS v6+
import { timer } from 'rxjs';
import { windowTime, tap, mergeAll } from 'rxjs/operators';

//emit immediately then every 1s
const source = timer(0, 1000);
const example = source.pipe(
  //start new window every 3s
  windowTime(3000),
  tap(_ => console.log('NEW WINDOW!'))
);

const subscribeTwo = example
  .pipe(
    //window emits nested observable
    mergeAll()
    /*
            output:
            "NEW WINDOW!"
            0
            1
            2
            "NEW WINDOW!"
            3
            4
            5
          */
  )
  .subscribe(val => console.log(val));
```

### Additional Resources

* [windowTime](https://rxjs.dev/api/operators/windowTime) 📰 - Official docs

***

> 📁 Source Code: <https://github.com/ReactiveX/rxjs/blob/master/packages/rxjs/src/internal/operators/windowTime.ts>


# windowToggle

#### signature: `windowToggle(openings: Observable, closingSelector: function(value): Observable): Observable`

## Collect and emit observable of values from source between opening and closing emission.

### Examples

**Example 1: Toggle window at increasing interval**

( [StackBlitz](https://stackblitz.com/edit/typescript-3nsyte?file=index.ts\&devtoolsheight=100) | [jsBin](http://jsbin.com/xasofupuka/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/3xmmuzy4/) )

```js
// RxJS v6+
import { timer, interval } from 'rxjs';
import { tap, windowToggle, mergeAll } from 'rxjs/operators';

//emit immediately then every 1s
const source = timer(0, 1000);
//toggle window on every 5
const toggle = interval(5000);
const example = source.pipe(
  //turn window on every 5s
  windowToggle(toggle, val => interval(val * 1000)),
  tap(_ => console.log('NEW WINDOW!'))
);

const subscribeTwo = example
  .pipe(
    //window emits nested observable
    mergeAll()
    /*
            output:
            "NEW WINDOW!"
            5
            "NEW WINDOW!"
            10
            11
            "NEW WINDOW!"
            15
            16
            "NEW WINDOW!"
            20
            21
            22
          */
  )
  .subscribe(val => console.log(val));
```

### Additional Resources

* [windowToggle](https://rxjs.dev/api/operators/windowToggle) 📰 - Official docs
* [Split an RxJS observable conditionally with windowToggle](https://egghead.io/lessons/rxjs-split-an-rxjs-observable-conditionally-with-windowtoggle?course=use-higher-order-observables-in-rxjs-effectively) 🎥 💵 - André Staltz

***

> 📁 Source Code: <https://github.com/ReactiveX/rxjs/blob/master/packages/rxjs/src/internal/operators/windowToggle.ts>


# windowWhen

#### signature: `windowWhen(closingSelector: function(): Observable): Observable`

## Close window at provided time frame emitting observable of collected values from source.

### Examples

**Example 1: Open and close window at interval**

( [StackBlitz](https://stackblitz.com/edit/typescript-52tu8k?file=index.ts\&devtoolsheight=100) | [jsBin](http://jsbin.com/tuhaposemo/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/gnx9fb3h/) )

```js
// RxJS v6+
import { interval, timer } from 'rxjs';
import { windowWhen, tap, mergeAll } from 'rxjs/operators';

//emit immediately then every 1s
const source = timer(0, 1000);
const example = source.pipe(
  //close window every 5s and emit observable of collected values from source
  windowWhen(() => interval(5000)),
  tap(_ => console.log('NEW WINDOW!'))
);

const subscribeTwo = example
  .pipe(
    //window emits nested observable
    mergeAll()
    /*
      output:
      "NEW WINDOW!"
      0
      1
      2
      3
      4
      "NEW WINDOW!"
      5
      6
      7
      8
      9
    */
  )
  .subscribe(val => console.log(val));
```

### Additional Resources

* [windowWhen](https://rxjs.dev/api/operators/windowWhen) 📰 - Official docs

***

> 📁 Source Code: <https://github.com/ReactiveX/rxjs/blob/master/packages/rxjs/src/internal/operators/windowWhen.ts>


# Utility

From logging, handling notifications, to setting up schedulers, these operators provide helpful utilities in your observable toolkit.

## Contents

* [tap / do](/learn-rxjs/operators/utility/do) ⭐
* [delay](/learn-rxjs/operators/utility/delay) ⭐
* [delayWhen](/learn-rxjs/operators/utility/delaywhen)
* [dematerialize](/learn-rxjs/operators/utility/dematerialize)
* [finalize / finally](/learn-rxjs/operators/utility/finalize)
* [let](/learn-rxjs/operators/utility/let)
* [repeat](/learn-rxjs/operators/utility/repeat)
* [repeatWhen](https://github.com/btroncone/learn-rxjs/blob/master/operators/utility/repeatwhen.md)
* [timeInterval](/learn-rxjs/operators/utility/timeinterval)
* [timeout](/learn-rxjs/operators/utility/timeout)
* [timeoutWith](/learn-rxjs/operators/utility/timeoutwith)
* [toPromise](/learn-rxjs/operators/utility/topromise)

⭐ - *commonly used*


# tap / do

#### signature: `tap(nextOrObserver: function, error: function, complete: function): Observable`

## Transparently perform actions or side-effects, such as logging.

***

💡 If you are using and old version of RxJS, `tap` used to be known as `do`!

***

### Why use `tap`?

Think of `tap` as a surveillance camera in a shopping mall. It doesn't interfere with the shoppers (values) moving around but merely observes and records their actions. This operator is best for side effects: actions you want to take in response to values in an observable, without affecting the values themselves.

One of the superpowers of `tap` is its utility in debugging. **When things aren't going as planned with your observable**, instead of tearing apart your chain or inserting numerous logs, simply sprinkle in some `tap` operators. It's like adding checkpoints in a video game, helping you swiftly pinpoint issues without disrupting the main flow.

However, a word of caution: **remember that `tap` is solely for side effects**. If you find yourself tempted to modify data within a `tap`, it's generally best to resist. That's not its purpose, and you're better off with [`map`](/learn-rxjs/operators/transformation/map) or other transformational operators in these cases.

Lastly, it's best to ensure that the side effects you introduce via `tap` are not critical to the main logic of your observable chain, keeping them non-intrusive and harmless.

### Examples

**Example 1: Logging with tap**

( [StackBlitz](https://stackblitz.com/edit/typescript-cd2gjp?file=index.ts\&devtoolsheight=100) | [jsBin](http://jsbin.com/jimazuriva/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/qtyakorq/) )

```js
// RxJS v6+
import { of } from 'rxjs';
import { tap, map } from 'rxjs/operators';

const source = of(1, 2, 3, 4, 5);
// transparently log values from source with 'tap'
const example = source.pipe(
  tap(val => console.log(`BEFORE MAP: ${val}`)),
  map(val => val + 10),
  tap(val => console.log(`AFTER MAP: ${val}`))
);

//'tap' does not transform values
//output: 11...12...13...14...15
const subscribe = example.subscribe(val => console.log(val));
```

**Example 2: Using tap with object**

( [StackBlitz](https://stackblitz.com/edit/typescript-3xykpb?file=index.ts\&devtoolsheight=100))

```js
// RxJS v6+
import { of } from 'rxjs';
import { tap, map } from 'rxjs/operators';

const source = of(1, 2, 3, 4, 5);

// tap also accepts an object map to log next, error, and complete
const example = source
  .pipe(
    map(val => val + 10),
    tap({
      next: val => {
        // on next 11, etc.
        console.log('on next', val);
      },
      error: error => {
        console.log('on error', error.message);
      },
      complete: () => console.log('on complete')
    })
  )
  // output: 11, 12, 13, 14, 15
  .subscribe(val => console.log(val));
```

### Related Recipes

* [Battleship Game](/learn-rxjs/recipes/battleship-game)
* [Breakout Game](/learn-rxjs/recipes/breakout-game)
* [Car Racing Game](/learn-rxjs/recipes/car-racing-game)
* [Catch The Dot Game](/learn-rxjs/recipes/catch-the-dot-game)
* [Click Ninja Game](/learn-rxjs/recipes/click-ninja-game)
* [Flappy Bird Game](/learn-rxjs/recipes/flappy-bird-game)
* [Horizontal Scroll Indicator](/learn-rxjs/recipes/horizontal-scroll-indicator)
* [Lockscreen](/learn-rxjs/recipes/lockscreen)
* [Memory Game](/learn-rxjs/recipes/memory-game)
* [Mine Sweeper Game](/learn-rxjs/recipes/mine-sweeper-game)
* [Platform Jumper Game](/learn-rxjs/recipes/platform-jumper-game)
* [Save Indicator](/learn-rxjs/recipes/save-indicator)
* [Space Invaders Game](/learn-rxjs/recipes/space-invaders-game)
* [Stop Watch](/learn-rxjs/recipes/stop-watch)
* [Swipe To Refresh](/learn-rxjs/recipes/swipe-to-refresh)
* [Tank Battle Game](/learn-rxjs/recipes/tank-battle-game)
* [Tetris Game](/learn-rxjs/recipes/tetris-game)
* [Type Ahead](/learn-rxjs/recipes/type-ahead)
* [Uncover Image Game](/learn-rxjs/recipes/uncover-image-game)

### Additional Resources

* [tap](https://rxjs.dev/api/operators/tap) 📰 - Official docs
* [Logging a stream with do](https://egghead.io/lessons/rxjs-logging-a-stream-with-do?course=step-by-step-async-javascript-with-rxjs) 🎥 💵 - John Linquist
* [Utility operator: do](https://egghead.io/lessons/rxjs-utility-operator-do?course=rxjs-beyond-the-basics-operators-in-depth) 🎥 💵 - André Staltz

***

> 📁 Source Code: <https://github.com/ReactiveX/rxjs/blob/master/packages/rxjs/src/internal/operators/tap.ts>


# delay

#### signature: `delay(delay: number | Date, scheduler: Scheduler): Observable`

## Delay emitted values by given time.

### Why use `delay`?

This operator is your go-to when simulating real-world scenarios such as network latency or introducing a pause before a value is emitted. The `delay` operator allows you to hold back values for a specified duration before they're released to subscribers.

Keep in mind that **`delay` won’t prevent the original observable from emitting values**. It merely postpones the delivery to its subscribers. This is a *gotcha* as it could look like your data is lagging or not in sync with the source, especially when multiple observables are at play.

### Examples

**Example 1: Delay to recognize long press**

( [StackBlitz](https://stackblitz.com/edit/rxjs-bru5fi?devtoolsheight=60) )

```js
import { fromEvent, of } from 'rxjs';
import { mergeMap, delay, takeUntil } from 'rxjs/operators';

const mousedown$ = fromEvent(document, 'mousedown');
const mouseup$ = fromEvent(document, 'mouseup');

mousedown$
  .pipe(mergeMap(event => of(event).pipe(delay(700), takeUntil(mouseup$))))
  .subscribe(event => console.log('Long Press!', event));
```

**Example 2: Delay for increasing durations**

( [StackBlitz](https://stackblitz.com/edit/typescript-twjn8r?file=index.ts\&devtoolsheight=100) )

```js
// RxJS v6+
import { of, merge } from 'rxjs';
import { mapTo, delay } from 'rxjs/operators';

//emit one item
const example = of(null);
//delay output of each by an extra second
const message = merge(
  example.pipe(mapTo('Hello')),
  example.pipe(mapTo('World!'), delay(1000)),
  example.pipe(mapTo('Goodbye'), delay(2000)),
  example.pipe(mapTo('World!'), delay(3000))
);
//output: 'Hello'...'World!'...'Goodbye'...'World!'
const subscribe = message.subscribe(val => console.log(val));
```

### Related Recipes

* [Battleship Game](/learn-rxjs/recipes/battleship-game)
* [Progress Bar](/learn-rxjs/recipes/progressbar)
* [Save Indicator](/learn-rxjs/recipes/save-indicator)
* [Swipe To Refresh](/learn-rxjs/recipes/swipe-to-refresh)

### Additional Resources

* [delay](https://rxjs.dev/api/operators/delay) 📰 - Official docs
* [Transformation operator: delay and delayWhen](https://egghead.io/lessons/rxjs-transformation-operators-delay-and-delaywhen?course=rxjs-beyond-the-basics-operators-in-depth) 🎥 💵 - André Staltz

***

> 📁 Source Code: <https://github.com/ReactiveX/rxjs/blob/master/packages/rxjs/src/internal/operators/delay.ts>


# delayWhen

#### signature: `delayWhen(selector: Function, sequence: Observable): Observable`

## Delay emitted values determined by provided function.

### Examples

**Example 1: Delay based on observable**

( [StackBlitz](https://stackblitz.com/edit/typescript-5yzn8g?file=index.ts\&devtoolsheight=100) | [jsBin](http://jsbin.com/topohekuje/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/b057mxkL/) )

```js
// RxJS v6+
import { interval, timer } from 'rxjs';
import { delayWhen } from 'rxjs/operators';

//emit value every second
const message = interval(1000);
//emit value after five seconds
const delayForFiveSeconds = () => timer(5000);
//after 5 seconds, start emitting delayed interval values
const delayWhenExample = message.pipe(delayWhen(delayForFiveSeconds));
//log values, delayed for 5 seconds
//ex. output: 5s....1...2...3
const subscribe = delayWhenExample.subscribe(val => console.log(val));
```

### Additional Resources

* [delayWhen](https://rxjs.dev/api/operators/delayWhen) 📰 - Official docs
* [Transformation operator: delay and delayWhen](https://egghead.io/lessons/rxjs-transformation-operators-delay-and-delaywhen?course=rxjs-beyond-the-basics-operators-in-depth) 🎥 💵 - André Staltz

***

> 📁 Source Code: <https://github.com/ReactiveX/rxjs/blob/master/packages/rxjs/src/internal/operators/delayWhen.ts>


# dematerialize

#### signature: `dematerialize(): Observable`

## Turn notification objects into notification values.

[![UltimateRxJS](https://ultimatecourses.com/static/banners/banner-rxjs.svg)](https://ultimatecourses.com/courses/rxjs?ref=4)

### Examples

**Example 1: Converting notifications to values**

( [StackBlitz](https://stackblitz.com/edit/typescript-bxdwbg?file=index.ts\&devtoolsheight=100) | [jsBin](http://jsbin.com/vafedocibi/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/jw08mouy/) )

```javascript
// RxJS v6+
import { from, Notification } from 'rxjs';
import { dematerialize } from 'rxjs/operators';

//emit next and error notifications
const source = from([
  Notification.createNext('SUCCESS!'),
  Notification.createError('ERROR!')
]).pipe(
  //turn notification objects into notification values
  dematerialize()
);

//output: 'NEXT VALUE: SUCCESS' 'ERROR VALUE: 'ERROR!'
const subscription = source.subscribe({
  next: val => console.log(`NEXT VALUE: ${val}`),
  error: val => console.log(`ERROR VALUE: ${val}`)
});
```

### Additional Resources

* [dematerialize](https://rxjs.dev/api/operators/dematerialize) 📰 - Official docs

> 📁 Source Code: [https://github.com/ReactiveX/rxjs/blob/master/packages/rxjs/src/internal/operators/demterialize.ts](https://github.com/ReactiveX/rxjs/blob/master/packages/rxjs/src/internal/operators/dematerialize.ts)


# finalize / finally

#### signature: `finalize(callback: () => void)`

## Call a function when observable completes or errors

### Examples

**Example 1: Execute callback function when the observable completes**

( [StackBlitz](https://stackblitz.com/edit/typescript-ohddud) )

```js
import { interval } from 'rxjs';
import { take, finalize } from 'rxjs/operators';

//emit value in sequence every 1 second
const source = interval(1000);
//output: 0,1,2,3,4,5....
const example = source.pipe(
  take(5), //take only the first 5 values
  finalize(() => console.log('Sequence complete')) // Execute when the observable completes
)
const subscribe = example.subscribe(val => console.log(val));
```

### Related Recipes

* [Battleship Game](/learn-rxjs/recipes/battleship-game)
* [Car Racing Game](/learn-rxjs/recipes/car-racing-game)
* [Click Ninja Game](/learn-rxjs/recipes/click-ninja-game)
* [HTTP Polling](/learn-rxjs/recipes/http-polling)
* [Mine Sweeper Game](/learn-rxjs/recipes/mine-sweeper-game)
* [Swipe To Refresh](/learn-rxjs/recipes/swipe-to-refresh)
* [Tetris Game](/learn-rxjs/recipes/tetris-game)

### Additional Resources

* [finalize](https://rxjs.dev/api/operators/finalize) 📰 - Official docs

***

> 📁 Source Code: <https://github.com/ReactiveX/rxjs/blob/master/packages/rxjs/src/internal/operators/finalize.ts>




---

[Next Page](/llms-full.txt/1)

