InquisitiveGirl
InquisitiveGirl

Reputation: 687

Redux-saga: Calling a saga outside the redux middleware environment

Pretty new to redux saga - I'm trying to figure out how to call a saga outside the redux middleware environment when I have access to the store.

After reading the redux saga docs looks like I have two options either call store.runSaga or use the runSaga utility provided by redux-saga.

This is what I'm trying to do:

Steps:

  1. Created a saga that pauses until the success action is dispatched.

Something like this:

      export function* loadDashboardSequenced() {

      try {
      // Take pauses until action received.
      //Wait for the user to be loaded
      const user_success = yield take('FETCH_USER_SUCCESS');
       // ....do other stuff....
        } catch(error) {
         yield put({type: 'FETCH_FAILED', error: error.message});
      }
  1. Now I'm trying to call the saga either via store.runSaga https://redux-saga.js.org/docs/api/ or runSaga https://redux-saga.js.org/docs/api/index.html#runsagaoptions-saga-args

Is there any benefits of using runSaga vs store.runSaga? I'm not sure which one I should use at this point. Any thoughts/suggestions? Thanks!

EDIT: followup question about using runSaga https://redux-saga.js.org/docs/advanced/UsingRunSaga.html What does this line mean

        subscribe: ..., // this will be used to resolve take Effects

Upvotes: 0

Views: 2420

Answers (2)

Hezi
Hezi

Reputation: 518

If you have a saga that retrieves data from a REST API and then hands off the data to a reducer ... then testing your saga without a store makes a lot of sense.

Furthermore, the thing I didn't like about the Beginner Tutorial tests, is that I wanted to test the full stack, client through to server. The tests in "Beginner Tutorial" cannot test that because they do not actually get the results of the saga's execution, just the call/put messages.

I would look at The best way to test Redux Sagas for full discussion, but here is a quick sample that summarizes Phil Herbert's post:

import { runSaga } from 'redux-saga'; // using runSaga to execute the saga
import { testMeSaga } from './sagas'; // the saga under test

test('test testMeSaga by running it', async () => {
    // 'recordSaga' is a utility function for running sagas, see it below.
    const result = await recordSaga(
        testMeSaga,
        { payload: 'your input to the saga' }
    );
    expect(result.length).toBe(1);    
    // add more checks here ...
});

// this is the utility function that wraps the running of the saga
async function recordSaga(saga, initialAction) {
    const dispatched = [];
    await runSaga(
        {
            dispatch: (action) => dispatched.push(action)
        },
        saga,
        initialAction
    ).done;

    return dispatched;
} 

Upvotes: 0

rcode
rcode

Reputation: 1888

The store.runSaga method is used to start the root saga for the store. It also expects redux-saga to be a store middleware :

export default function configureStore(initialState) {
  const sagaMiddleware = createSagaMiddleware()
  return {
    ...createStore(reducer, initialState, applyMiddleware(/* other middleware, */sagaMiddleware)),
    runSaga: sagaMiddleware.run
  }
}

const store = configureStore()
store.runSaga(rootSaga)

On the other hand, runSaga method is there for connecting redux-saga to non-store objects and interfaces, which is something you rarely do.

In summary, if you need sagas put and take methods to work with redux actions, then you you need to use redux-saga as store middleware.

Upvotes: 1

Related Questions