Skip to main content

API reference

Defaults​

defaultChannel​

Core

The defaultChannel is the default EventEmitter used to emit Actions, which can then be awaited.

defaultTree​

Core

The defaultTree is the default Tree object used to maintain the parent-child relationships of Sagas.

Helpers​

createAction​

Core

createAction(fn?, channel?) creates an Action, which can be either empty or a wrapper for a function or model method. When this function is called, an action is dispatched to the defaultChannel. Such actions can be awaited with take, for instance.

Arguments:

  1. fn?: FnActionInput - Function
  2. channel?: EventEmitter - Channel to dispatch an action, defaults to defaultChannel.

Returns: FnAction - Function action.

Example:

const changeNewTodoText = createAction(); // create an empty action

const addTodo = createAction((text: string) => { // wrap an existing function
// ...
});

See examples or even Zustand tutorial for more information.

createAsyncAction​

Core

createAsyncAction(fn?, channel?) creates an Action by wrapping an existing async function. It works the same as createAction, but awaits the async function's return result.

Arguments:

  1. fn?: FnActionInput - Async function
  2. channel?: EventEmitter - Channel to dispatch an action, defaults to defaultChannel.

Returns: FnAction<Promise> - Async function action.

Example:

const addTodo = createAsyncAction(async (text: string) => { // wrap an existing function
await Promise.resolve((resolve) => setTimeout(500, resolve));
// ...
});

createCreateSaga​

Core

createCreateSaga(config?) creates a createSaga function with a bound plugin and tree.

Arguments:

  • config: SagaConfig:
    • plugin?: SagaPlugin - Plugin with effects to inject into a wrapping async function. Merge plugins if you need more than one.
    • tree?: SagaTreeNode - Tree node object to maintain sagas' parent-child relationships.
    • onError?: (err: unknown, node: SagaTreeNode) => void - onError handler. Refer to error handling for more information.

Returns: createSaga function.

Example:

import {createCreateSaga} from '@promise-saga/core';
import {plugin} from '@promise-saga/plugin-redux';

// bind an plugin
export const createSaga = createCreateSaga({plugin});

const saga = createSaga(async function() {
await this.delay(500);
// dispatch a Redux action
await this.dispatch({type: 'actions/test'});
});

Merge plugins, if you need more than one. See tutorials and examples for more information.

createHigherHooks​

Angular React Redux Svelte Vue

createHigherHooks(createSaga?, useSaga?) creates a set of higher hooks.

Arguments:

  • createSaga: CreateSagaFunction - createSaga function. createCreateSaga creates its customized instance.
  • useSaga: UseSagaHook - useSaga hook. createUseSaga creates its customized instance.

Returns: Set of higher hooks.

Example:

import {createCreateSaga} from '@promise-saga/core';
import {createUseSaga} from '@promise-saga/plugin-react';
import {plugin, createHigherHooks} from '@promise-saga/plugin-redux';

export const createSaga = createCreateSaga({plugin});
export const useSaga = createUseSaga({
runOnMount: false,
});

export const {
useTakeEvery,
useTakeLeading,
useTakeLatest,
useDebounce,
useThrottle,
} = createHigherHooks(createSaga, useSaga);

createSaga​

Core

createSaga(saga, config?) creates a saga.

Arguments:

  • saga: SagaInput - Async function to wrap and produce a Saga. This function will eventually get all plugins and effects in this.
  • config: SagaConfig:
    • plugin?: SagaPlugin - Plugin with effects to inject into the wrapping async function. Merge plugins if you need more than one.
    • tree?: SagaTreeNode - Tree node object to maintain sagas' parent-child relationships.
    • onError?: (err: unknown, node: SagaTreeNode) => void - onError handler. Refer to error handling for more information.

Returns: Saga

Example:

const saga = createSaga(async function() {
await this.delay(500);
// ...
});

See tutorials and examples for more information.

createUseSaga​

Angular React Svelte Vue

createUseSaga(config?) creates a useSaga hook with preset configurations.

Arguments:

  • config: UseSagaConfig:
    • runOnMount?: boolean - Whether to run Saga on React component mount, defaults to true.
    • cancelOnUnmount?: boolean - Whether to cancel Saga on React component unmount, defaults to true.

Returns: useSaga hook.

Example:

import {createUseSaga} from '@promise-saga/plugin-react';
import {plugin} from '@promise-saga/plugin-redux';

export const useSaga = createUseSaga({
runOnMount: false,
cancelOnUnmount: false,
});

isAbortError​

Core

Arguments:

  • err: unknown - Presumed Error instance.

Returns: boolean

Helper to commonly refine errors from being handled. See the example in error handling.

import {isAbortError} from '@promise-saga/core';

export const saga = createSaga(async function () {
try {
await this.call(inner);
} catch (err) {
if (!isAbortError(err)) {
// handle error
}
}
});

mergePlugins​

Core

mergePlugins(...plugins) merges multiple plugins into a single one.

Arguments:

  • ...plugins: Plugin[] - Plugins with effects to inject.

Returns: Plugin object.

Example:

import {createCreateSaga, mergePlugins} from '@promise-saga/core';
import reduxPlugin from '@promise-saga/plugin-redux';
import fetchPlugin from '@promise-saga/plugin-fetch';

const plugin = mergePlugins(reduxPlugin, fetchPlugin);
export const createSaga = createCreateSaga({plugin});

Effects​

all​

Core

await this.all(iter[]) - runs several tasks concurrently until all of them succeed.

Arguments:

Returns: SagaIterator<iterResult[]> - awaits and returns a results array.

Example:

export const fetchAllPokemons = createSaga(async function() {
const [pikachu, raichu] = await this.all([
getPokemonData('pikachu'),
getPokemonData('raichu'),
]);
console.log({pikachu, raichu});
});

See concurrency for more information.

axios​

Axios

await this.get(url, options) - Fetches response by URL. Works similarly to post, put, delete, and others.

Arguments:

  • url: string - URL to fetch.
  • options: RequestConfig - Axios RequestConfig.

Returns:: AxiosResponse

Example:

import {createCreateSaga} from '@promise-saga/core';
import {plugin} from '@promise-saga/plugin-axios';

const createSaga = createCreateSaga({plugin});

export const getPokemonData = createSaga(async function(pokemon: string) {
const resp = await this.get<PokemonData>(`https://pokeapi.co/api/v2/pokemon/${pokemon}`);
return resp.data;
});

call​

Core

await this.call(saga, ...args) - Calls a Saga in a blocking way.

Arguments:

  • saga: Saga - Saga to call.

Returns: SagaIterator.

See composing and non-blocking calls for more information.

Example:

const saga = createSaga(async function() {
return 2;
});

const main = createSaga(async function() {
// call saga in a blocking way
const result = await this.call(saga);
console.log(result); // 2
});

See composing and non blocking calls for more information.

callFn​

Core

this.callFn(sagaFn, ...args) - Calls a function.

Arguments:

  • sagaFn: Function - Function to be called.

Returns: Function return result.

Example:

const fn = () => 2;

const main = createSaga(async function() {
const result = this.callFn(fn); // 2
// ...
});

See composing for more information.

callPromise​

Core

await this.callPromise(promise) - Calls a promise.

Arguments:

  • promise: Promise - Promise to be called.

Returns: Promise return result.

Example:

const promise = Promise.resolve(2);

const main = createSaga(async function() {
const result = await this.callPromise(promise); // 2
// ...
});

See composing for more information.

cancel​

Core

this.cancel(iter?) - Cancels a non-blocking task or the current saga.

Arguments:

  • iter?: SagaIterator - SagaIterator or simply a task to be cancelled.

Example:

const saga = createSaga(async function() {
// call child saga in a non-blocking way
const task = this.fork(childSaga);
// ...perform saga logic
this.cancel(task); // cancel task
});

See non blocking calls for more information.

cancellable​

Core

this.cancellable(promise, config?) - Creates a cancellable promise, primarily used to create custom effects. For example:

Arguments:

  • promise: Promise - Input promise.
  • config: CancellableConfig:
    • onFinally?: () => void - Function called on success, error, and cancellation. Can be used to teardown and unsubscribe from everything.
    • onError?: (err: unknown) => void - Function called on error.

Returns: SagaIterator.

Example: delay effect on github

export async function delay(this: SagaLowerEffectsScope, ms?: number) {
this.throwIfCancelled();
let timeout: NodeJS.Timeout;

// create a cancellable setTimeout
return this.cancellable<void>(new Promise((resolve) => {
timeout = setTimeout(() => {
this.throwIfCancelled();
resolve();
}, ms);
}), {
onFinally: () => clearTimeout(timeout), // finally clearTimeout
});
}

cancelled​

Core

this.cancelled(iter?) - Checks if a non-blocking task or the current saga has already been cancelled.

Arguments:

  • iter?: SagaIterator - SagaIterator or simply a task to be cancelled.

Returns: boolean.

Example:

const parentSaga = createSaga(async function() {
// call child saga in a non-blocking way
const task = this.fork(childSaga);
// ...
await this.delay(1500); // perform saga logic
this.cancel(task); // cancel task after 1500ms
});

const childSaga = createSaga(async function() {
try {
await this.delay(3000); // perform saga logic for 3000ms
console.log('success!');
} finally {
console.log('finally', this.cancelled()); // true
}
});

See non blocking calls for more information.

debounce​

Default Redux

this.debounce(ms, action, saga, ...args) - Delays the execution of a Saga until the user stops performing an action for a specified amount of time.

Arguments:

  • ms: number - Amount of time in milliseconds.
  • action: Action - Action to wait for.
  • saga: Saga - Saga to call.
  • args: any[] - Additional saga arguments to call with. The first saga incoming argument is the action that triggered it.

Returns: SagaIterator.

Example:

const saga = createSaga(async function() {
this.debounce(500, Todos.actions.toggleTodo, toggleTodo);
});

const toggleTodo = createSaga(async function() {
// ...
});

See debouncing and throttling for more information.

delay​

Core

await this.delay(ms?) - Waits for a specified amount of time in milliseconds.

Arguments:

  • ms?: number - Amount of time in milliseconds.

Example:

const saga = createSaga(async function() {
await this.delay(500);
console.log('done');
});

dispatch​

Redux

this.dispatch(action) - Dispatches a Redux action into a Store.

Arguments:

  • action: Action - Redux action.

Example:

import {createAction} from '@reduxjs/toolkit';

export const addTodo = createAction<string>('todos/add');

export const startPokemonsRace = createSaga(async function() {
this.dispatch(addTodo('new todo'));
// ...
});

See redux tutorial for more information.

fetch​

Fetch

await this.fetch(url, options) - Fetches a response by URL.

Arguments:

  • url: string - URL to fetch.
  • options: RequestInit - Fetch request options.

Returns: Promise<T>.

Example:

export const getPokemonData = createSaga(async function(pokemon: string) {
const resp = await this.fetch(`https://pokeapi.co/api/v2/pokemon/${pokemon}`);
const data: PokemonData = await resp.json();
return data;
});

fork​

Core

this.fork(saga, ...args) - Forks a Saga in a detached non-blocking way.

Arguments:

  • saga: Saga - Saga to fork.

Returns: SagaIterator.

Example:

const saga = createSaga(async function() {
// ...
});

const main = createSaga(async function() {
const task = this.fork(saga);
// returned task can be cancelled, when you need it
this.cancel(task);
});

See non blocking calls for more information.

getStore​

Redux

this.getStore() - Returns a Redux Store inside a Saga. It may allow you some special usage of the Redux Store API.

Returns: Store.

Example:

import {Selector} from '@reduxjs/toolkit';

export const getTodos: Selector<RootState, Todo[]> = (state) => state.todos.todos;

const saga = createSaga(async function() {
// manual selector usage
const todos = getTodos(this.getStore().getState());
});

observable​

Core

this.observable(value) - Observes a value for its changes and provides a listener.

Arguments:

  • value: any - Observing value.

Returns: Observable.

Example:

const saga = createSaga(async function() {
const isOpen = this.observable(false); // create a boolean observable

setTimeout(() => {
isOpen.setValue(true); // set isOpen to true after 100ms
}, 100);

await this.race([
isOpen.onValue(true), // wait isOpen to become true
this.delay(500), // within timeout 500ms
]);
});

race​

Core

await this.race(iter[]) - Runs several tasks concurrently until one of them succeeds.

Arguments:

Returns: SagaIterator<(iterResult | undefined)[]> - awaits and returns a results array with multiple undefineds and a single result filled in.

Example:

import {createAction} from '@reduxjs/toolkit';

export const cancelAction = createAction('action/cancel');

export const startPokemonsRace = createSaga(async function() {
const [pikachu, raichu] = await this.race([
getPokemonData('pikachu'),
getPokemonData('raichu'),
this.delay(500), // automatic cancel in 500 ms
this.take(cancelAction), // manual cancel on action dispatch
]);
console.log({pikachu, raichu});
});

See concurrency for more information.

select​

Redux

this.select(selector) - Returns a Redux selector result.

Arguments:

  • selector: Selector - Selector to be applied.

Returns: Selector result.

Example:

import {Selector} from '@reduxjs/toolkit';

export const getTodos: Selector<RootState, Todo[]> = (state) => state.todos.todos;

const saga = createSaga(async function() {
const todos = this.select(getTodos);
// ...
});

See redux tutorial for more information.

spawn​

Core

this.spawn(saga, ...args) - Calls a Saga in a non-blocking detached way. Canceling the parent will not cause the cancellation of itself.

Arguments:

  • saga: Saga - Saga to call.

Returns: SagaIterator.

Example:

const saga = createSaga(async function() {
const task = this.spawn(childSaga);
// ...perform saga logic
this.cancel(task);
});

See non blocking calls for more information.

take​

Default Redux

await this.take(action) - Waits for a Redux/Zustand action to happen.

Arguments:

  • action: Action - Redux action to wait for.

Returns: SagaIterator.

Example:

import {createAction} from '@reduxjs/toolkit';

const testAction = createAction('actions/test');

const saga = createSaga(async function() {
const action = await this.take(testAction);
console.log('done!', action); // { type: "actions/test" }
});

See future actions for more information.

takeEvery​

Default Redux

this.takeEvery(action, saga, ...args) - Binds a saga call to every action happening.

Arguments:

  • action: Action - Action to wait for.
  • saga: Saga - Saga to call.
  • args: any[] - Additional saga arguments to call with. The first saga incoming argument is the action that triggered it.

Returns: SagaIterator.

Example:

// common watcher saga
const main = createSaga(async function() {
this.takeEvery(testAction1, saga1);
this.takeLatest(testAction2, saga2);
this.takeLeading(testAction3, saga3);
});

See future actions for more information.

takeLeading​

Default Redux

this.takeLeading(action, saga, ...args) - Binds a saga call to the leading action happening.

Arguments:

  • action: Action - Action to wait for.
  • saga: Saga - Saga to call.
  • args: any[] - Additional saga arguments to call with. The first saga incoming argument is the action that triggered it.

Returns: SagaIterator.

See takeEvery example and future actions for more information.

takeLatest​

Default Redux

this.takeLatest(action, saga, ...args) - Binds a saga call to the latest action happening.

Arguments:

  • action: Action - Action to wait for.
  • saga: Saga - Saga to call.
  • args: any[] - Additional saga arguments to call with. The first saga incoming argument is the action that triggered it.

Returns: SagaIterator.

See takeEvery example and future actions for more information.

throttle​

Default Redux

this.throttle(ms, action, saga, ...args) - Limits the execution of a Saga to once in every specified time interval.

Arguments:

  • ms: number - Time interval in milliseconds.
  • action: Action - Action to wait for.
  • saga: Saga - Saga to call.
  • args: any[] - Additional saga arguments to call with. The first saga incoming argument is the action that triggered it.

Returns: SagaIterator.

Example:

const saga = createSaga(async function() {
this.throttle(500, Todos.actions.addTodo, addTodo);
});

const addTodo = createSaga(async function() {
// ...
});

See debouncing and throttling for more information.

throwIfCancelled​

Core

this.throwIfCancelled() - Throws an error with a reason, custom or default. This effect is similar to AbortSignal throwIfCancelled and is often used.

It can be used manually to cancel some heavy synchronous logic without effects in the process. For example:

const getHeavyResult = createSaga(async function() {
let i = 0;

while (i < 1e8) { // heavy task
i++;

if (i % 1e2 === 0) { // check if aborted each 100 iterations
this.throwIfCancelled();
}
}

return i;
});

Hooks​

useDebounce​

Angular React Redux Svelte Vue

useDebounce(ms, action, saga, ...args) - Wraps debounce into a hook.

Arguments:

  • ms: number - Amount of time in milliseconds.
  • action: Action - Action to wait for.
  • saga: Saga - Saga to call.
  • args: any[] - Additional saga arguments to call with. The first saga incoming argument is the action that triggered it.

See debouncing and throttling for more information.

Example:

import React, {useState} from 'react';
import {createAction} from '@promise-saga/plugin-default';
import {createSaga, useDebounce} from '../zustandSaga';

// create an empty action to trigger manually on search text changed
const searchAction = createAction<void, [string]>();

export function SearchBlock() {
// create a React state
const [searchResults, setSearchResults] = useState<SearchResult[]>([]);

// debounce searchAction with 500ms delay and call a saga
useDebounce(500, searchAction, createSaga(async function({args: [pattern]}) {
// mutate a React state
setSearchResults(searchRegistry.search(pattern));
}));

// ...
}

See debouncing and throttling for more information.

useSaga​

Angular React Svelte Vue

useSaga(saga, ...args) - Calls a Saga, previously created with createSaga, with arguments within a React component. This way, the saga runs on component mount and is cancelled on unmount.

Example:

const SagaCheckbox = ({flow}: {flow: ReturnType<typeof useSaga>}) => (
<input type="checkbox" onChange={flow.toggle} checked={flow.isRunning} />
);

export default function App() {
const listenTogglesFlow = useSaga(listenTodoToggles);

return (
<label>
<SagaCheckbox flow={listenTogglesFlow} />
Log todos toggling, count by 3
</label>
);
}

useTakeEvery​

Angular React Redux Svelte Vue

useTakeEvery(action, saga, ...args) - Wraps takeEvery into a hook.

Arguments:

  • action: Action - Action to wait for.
  • saga: Saga - Saga to call.
  • args: any[] - Additional saga arguments to call with. The first saga incoming argument is the action that triggered it.

Returns: SagaIterator.

See future actions for more information.

Example:

import React, {useState} from 'react';
import {createAction} from '@promise-saga/plugin-default';
import {createSaga, useDebounce} from '../zustandSaga';

// create an empty action to trigger manually on search text changed
const searchAction = createAction<void, [string]>();

export function SearchBlock() {
// create a React state
const [searchResults, setSearchResults] = useState<SearchResult[]>([]);

// take every searchAction and call a saga
useTakeEvery(searchAction, createSaga(async function({args: [pattern]}) {
// mutate a React state
setSearchResults(searchRegistry.search(pattern));
}));

// ...
}

See future actions for more information.

useTakeLeading​

Angular React Redux Svelte Vue

useTakeLeading(action, saga, ...args) - Wraps takeLeading into a hook.

Arguments:

  • action: Action - Action to wait for.
  • saga: Saga - Saga to call.
  • args: any[] - Additional saga arguments to call with. The first saga incoming argument is the action that triggered it.

Returns: SagaIterator.

See useTakeEvery example and future actions for more information.

useTakeLatest​

Angular React Redux Svelte Vue

useTakeLatest(action, saga, ...args) - Wraps takeLatest into a hook.

Arguments:

  • action: Action - Action to wait for.
  • saga: Saga - Saga to call.
  • args: any[] - Additional saga arguments to call with. The first saga incoming argument is the action that triggered it.

Returns: SagaIterator.

See useTakeEvery example and future actions for more information.

useThrottle​

Angular React Redux Svelte Vue

useThrottle(ms, action, saga, ...args) - Wraps throttle into a hook.

Arguments:

  • ms: number - Time interval in milliseconds.
  • action: Action - Action to wait for.
  • saga: Saga - Saga to call.
  • args: any[] - Additional saga arguments to call with. The first saga incoming argument is the action that triggered it.

See useDebounce example and future actions for more information.