Skip to main content

generate

Generates an Observable by running a state-driven loop that emits an element on each iteration.

Import

import { generate } from 'rxjs';

Type Signature

// Options object form
function generate<S>(
  options: GenerateBaseOptions<S>
): Observable<S>;

function generate<T, S>(
  options: GenerateOptions<T, S>
): Observable<T>;

// Separate arguments form (deprecated)
function generate<T, S>(
  initialState: S,
  condition: (state: S) => boolean,
  iterate: (state: S) => S,
  resultSelector?: (state: S) => T,
  scheduler?: SchedulerLike
): Observable<T>;

Parameters

options
GenerateOptions<T, S>
required
Configuration object with the following properties:
initialState
S
required
Initial state value
condition
(state: S) => boolean
Function that returns true to continue, false to complete. If omitted, generates infinitely.
iterate
(state: S) => S
required
Function that produces the next state
resultSelector
(state: S) => T
Function to transform the state before emission
scheduler
SchedulerLike
Scheduler to use for emissions

Returns

Observable
Observable<T>
An Observable that emits values generated by the loop

Description

generate is like a for loop as an Observable. It’s perfect when you need to create a sequence of values based on an evolving state. Think of it as:
for (let state = initialState; condition(state); state = iterate(state)) {
  emit(resultSelector ? resultSelector(state) : state);
}

Examples

Basic Number Sequence

import { generate } from 'rxjs';

const result$ = generate(0, x => x < 3, x => x + 1);

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

// Output:
// 0
// 1
// 2

With Result Selector

import { generate } from 'rxjs';

const result$ = generate(0, x => x < 3, x => x + 1, x => x * 1000);

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

// Output:
// 0
// 1000
// 2000

Using Options Object

import { generate } from 'rxjs';

const result$ = generate({
  initialState: 0,
  condition: x => x < 3,
  iterate: x => x + 1,
  resultSelector: x => x * 1000
});

result$.subscribe({
  next: x => console.log(x),
  complete: () => console.log('Complete!')
});

Common Use Cases

Fibonacci Sequence

import { generate } from 'rxjs';
import { take } from 'rxjs/operators';

const fibonacci$ = generate(
  { current: 0, next: 1 },
  () => true,
  ({ current, next }) => ({ current: next, next: current + next }),
  ({ current }) => current
).pipe(take(10));

fibonacci$.subscribe(x => console.log(x));
// Output: 0, 1, 1, 2, 3, 5, 8, 13, 21, 34

Power of Two

import { generate } from 'rxjs';

const powers$ = generate({
  initialState: 1,
  condition: x => x <= 1024,
  iterate: x => x * 2
});

powers$.subscribe(x => console.log(x));
// Output: 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024

Countdown Timer

import { generate, asyncScheduler } from 'rxjs';

const countdown$ = generate({
  initialState: 10,
  condition: x => x >= 0,
  iterate: x => x - 1,
  scheduler: asyncScheduler
});

countdown$.subscribe({
  next: x => console.log(x),
  complete: () => console.log('Blast off!')
});

Tips

Use the options object form for better readability and to avoid the deprecated separate arguments form.
Omit the condition function to create an infinite Observable. Use operators like take or takeWhile to limit emissions.
  • range - Simple number sequence
  • interval - Emit numbers periodically
  • defer - Lazy Observable creation

See Also