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. Applying the Saga Pattern (Youtube video) By Caitie McCaffrey
  2. Original paper By Hector Garcia-Molina & Kenneth Salem
  3. A Saga on Sagas from MSDN site

Official Logo

Redux Saga

2156 questions
15
votes
1 answer

Order of reducer and saga

When dispatching an action is the order when it arrives to a reducer and a saga guaranteed? Can I rely on that it first enters the reducer then the saga? Reducer: function reducer(state, action) { switch (action.type) { case…
Amio.io
  • 17,083
  • 11
  • 66
  • 100
15
votes
1 answer

Using put inside anonymous function callback

I am implementing Pusher into my React+Redux Saga application, but I am having a few problems with some callbacks where I can not hit the put(...) methods. Using console.log(...) etc. in the methods does show, but I am not able to put to the state…
janhartmann
  • 13,440
  • 13
  • 78
  • 130
15
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
  • 21,944
  • 17
  • 64
  • 88
14
votes
2 answers

Problem with select in redux-saga. Error: call: argument of type {context, fn} has undefined or null `fn`

After looking through some answers to similar questions here, I just can't get my selector to work. Here's my selector.js: export const getButtonStatus = state => state.buttonStatus; (That's the entirety of the file. I don't know if I have to…
blutarch
  • 143
  • 1
  • 6
14
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,332
  • 1
  • 15
  • 22
13
votes
2 answers

How to test redux-saga delay

Problem In redux-saga, I am using yield delay(1000);. During my unit test, I do expect(generator.next().value).toEqual(delay(1000));. I expect the test to pass. This is my sagas.js: import { delay } from 'redux-saga'; export function*…
Dimitri Kopriwa
  • 8,478
  • 12
  • 70
  • 140
13
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,332
  • 1
  • 15
  • 22
13
votes
1 answer

Invalid mapStateToProps Argument in React-Redux

I'm facing a problem with mapStateToProps argument. It seems a very simple error but I'm not able to figure out what's happening. Basically, what I'm trying to do is toggle a sidebar menu with react-redux and react saga. Everything works well but…
Pablo Darde
  • 3,855
  • 6
  • 29
  • 47
13
votes
2 answers

What is the point of unit testing redux-saga watchers?

In order to get 100% coverage of my Saga files I'm looking into how to test watchers. I've been googling around, there are several answers as to HOW to test watchers. That is, saga's that do a takeEvery or takeLatest. However, all methods of testing…
publicJorn
  • 1,914
  • 1
  • 16
  • 27
13
votes
1 answer

Redux Sagas, TypeScript, and call?

As a TypeScript and redux-thunk user, I am curious about the benefits offered by redux-saga. I'd like to give it a shot but am concerned about the call function and the apparent loss of type safety. If I do this: function* invalidateReddit():…
subvertallchris
  • 4,802
  • 2
  • 22
  • 36
13
votes
3 answers

How to get action.params from saga

I am using redux-saga. In the code yield* ReduxSaga.takeEvery('MY_ACTION', updatePorts); how can I access the action to get its fields. For example I have an action creator: function status(){ type: 'MY_ACTION', status: true } How can I access…
Amio.io
  • 17,083
  • 11
  • 66
  • 100
12
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
  • 21,469
  • 23
  • 94
  • 144
12
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
  • 5,158
  • 8
  • 38
  • 79
12
votes
3 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
  • 45,997
  • 54
  • 176
  • 303
12
votes
3 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
  • 337
  • 1
  • 3
  • 14