Questions tagged [redux-saga]

Redux-saga is a redux middleware library which designed for handling side effects in redux applications. It provides developers with the ability to manage asynchronous code synchronously.

Overview

middleware sits on top of redux applications, between actions and reducers more specifically. It mitigates application state transitions and side effects. As a result, flows are easier to manage, more efficient to execute, easier to test, and better at handling failures.

Use Case

Fetching data from API can be a common use case for using for handling side effects while the app is running in the background. This task is asynchronous as we can't be 100% sure if and when promised data will be available for our use. That results in poor user experience as we cannot guarantee the time it would take to display the data they need. By using a saga, we can stop function execution and wait until the data is ready, and then move forward to execute the next line of code. As [tag:redux saga], we'll usually want to display a loading indicator for signaling the status of the call to our users, resulting in better user experience at the end.

Example

function fetchJson(url) {
    return fetch(url)
    .then(request => request.text())
    .then(text => {
        return JSON.parse(text);
    })
    .catch(error => {
        console.log(`ERROR: ${error.stack}`);
    });
}

can be written as (with the help of libraries such as co.js)—

function * fetchJson(url) {
    try {
        let request = yield fetch(url);
        let text = yield request.text();
        return JSON.parse(text);
    }
    catch (error) {
        console.log(`ERROR: ${error.stack}`);
    }
};

Resources

  1. Redux-Saga Homepage
  2. Applying the Saga Pattern (Youtube video) By Caitie McCaffrey
  3. Original paper By Hector Garcia-Molina & Kenneth Salem
  4. A Saga on Sagas from MSDN site

Official Logo

Redux Saga

2491 questions
20
votes
1 answer

Where to store Class instance for reusability in Redux?

I am trying to implement a messaging library Chatkit by Pusher in my React/Redux/redux saga app and I'm new to Redux. The code for connecting to chatkit looks like this: const chatManager = new ChatManager({ instanceLocator:…
jonhobbs
  • 26,684
  • 35
  • 115
  • 170
19
votes
2 answers

Why does a test fail when using findBy but succeed when using waitfor?

Using react-testing-library, the following test works: it( 'renders popular search terms, with links to search urls', () => { waitFor(() => { const popularSearch = screen.getByText( Copywriting.buyer.shop.popularSearch, {}, { timeout:…
19
votes
2 answers

How to debug rxjs5?

On RxJS - Goals I read that their goal is better debuggability: Goals Provide more debuggable call stacks than preceding versions of RxJS I have just started to use redux-observable which is quite easier for me to understand comparing it to…
Amio.io
  • 20,677
  • 15
  • 82
  • 117
18
votes
1 answer

How can I get redux-saga to wait for two actions to happen at least once in any order?

Redux saga noob here. I need to create a saga that loads the initial state for the redux store from my API server. This involves using two async sagas: getCurrentUser and getGroups. I need to issue these ajax requests in parallel and wait for the…
momo
  • 975
  • 1
  • 8
  • 8
18
votes
1 answer

Can I use redux-saga's es6 generators as onmessage listener for websockets or eventsource?

I'm trying to get redux-saga working with the onmessage listener. I don't know why what I have isn't working. I have the following set-up. // sagas.js import { take, put } from 'redux-saga'; import {transactions} from "./actions"; function* foo…
user5325596
  • 2,310
  • 4
  • 25
  • 42
17
votes
2 answers

TypeScript: Use types on call() from redux-saga

How can I set the types of a function using call()? I have this function: export function apiFetch(url: string): Promise { return fetch(url).then(response => { if (!response.ok) throw new Error(response.statusText) …
Rumpelstinsk
  • 3,107
  • 3
  • 30
  • 57
17
votes
1 answer

Best way to listen for actions in saga: `while(true) take()` vs `while(take())` vs. `takeEvery()`

I've seen sagas listening for actions in 3 ways: 1. while(true) take() function* onUserDetailsRequest() { while(true) { const { userId } = yield take(USER_DETAILS_REQUESTED); const response = yield call(fetchUserDetails, userId); …
Ali Saeed
  • 1,519
  • 1
  • 16
  • 23
17
votes
5 answers

How to tie emitted events events into redux-saga?

I'm trying to use redux-saga to connect events from PouchDB to my React.js application, but I'm struggling to figure out how to connect events emitted from PouchDB to my Saga. Since the event uses a callback function (and I can't pass it a…
mikl
  • 23,749
  • 20
  • 68
  • 89
16
votes
1 answer

The delay functionality from redux saga is not working

Im trying to use the delay functionality but I get an error that delay is not a function. Straight from the docs: import { race, call, put, delay } from 'redux-saga/effects' function* fetchPostsWithTimeout() { const {posts, timeout} =…
Tzvetlin Velev
  • 1,897
  • 2
  • 17
  • 31
16
votes
4 answers

Using redux-saga with setInterval - how and when to yield

Having just moved from thunks to sagas I'm trying to find the best way to call setTimeout and then from within that function call another function (in this case corewar.step()). This was my original code which works as I'd expect. runner =…
dougajmcdonald
  • 19,231
  • 12
  • 56
  • 89
16
votes
1 answer

Difference between yield [] & yield all() - ES6/redux-saga

Is there any advantage in using redux-saga's yield all([]) over ES6's built-in yield []? To run multiple operations in parallel, redux-saga suggests: const result = yield all([ call(fetchData), put(FETCH_DATA_STARTED), ]); But the same can be…
Ali Saeed
  • 1,519
  • 1
  • 16
  • 23
16
votes
4 answers

redux saga and history.push

Backgrond: I am creating a Login component. saga.js is composed by 3 functions 1. rootSaga. It will execute the list of sagas inside 2. watchSubmitBtn. It will watch the click on the submit button and dispatch an action. 3. shootApiTokenAuth will…
joe
  • 8,383
  • 13
  • 61
  • 109
16
votes
2 answers

redux-saga: call vs fork and join

In redux-saga, for what reasons might you favor using call vs. fork and join? For example, when calling an HTTP API, what are the pros and cons of doing this: const result = yield call(apiWrapperFunction, arg1, arg2) versus this: const task = yield…
James Nail
  • 1,541
  • 1
  • 14
  • 23
16
votes
4 answers

Waiting in a redux-saga

I want to introduce a delay in a saga (using redux-saga). How can I do this? If redux-saga provides an API, I would also be interested in how to achieve it manually. function* save({ payload }) { yield put(pending()); // I want to simply…
Ben Aston
  • 53,718
  • 65
  • 205
  • 331
15
votes
4 answers

Is there a way to wait for an action in redux-sagas?

I have a saga (A) which fetches the API. This is tied with action (a). I want to trigger an action (b) which internally calls (a), waits for it to finish and then yield something. // saga A -> action_a function *saga_a(action) { yield put(…
ankit_m
  • 417
  • 2
  • 5
  • 16