redux-saga: Sagas started with runSaga can't take actions from Saga started with the middleware

Let’s say I have 2 sagas:

  1. simple api saga that was provided to middleware:
function* apiSaga(getState){
   while(true){
      const action  = yield take('API')
      const { result, error } = yield call(requestApiService, action)
      const [reqType, successType, failType ] = action.types

      yield put({ type: reqType, action })
      if(error) {
         yield put({ type: failType, error })
      } else {
         yield put({ type: successType, result})
      }
   }
}
  1. another saga, that I want to call with runSaga method:
function* routeResolveSaga(getState){
   yield put({ type: 'API', ..... types: ['ACTION_REQUEST', 'ACTION_SUCCESS', 'ACTION_FAIL'] })
   yield take(['ACTION_SUCCESS', 'ACTION_FAIL'])
}

When I call

runSaga(function*(getState){ 
  yield call(routeResolveSaga, getState) 
}(store.getState), storeIO(store))

apiSaga takes API action, after request is puts new action ACTION_SUCCESS or ACTION_FAIL, routeResolveSaga is waiting to take it, but nothing happens.

Maybe I have missed something?

About this issue

  • Original URL
  • State: closed
  • Created 8 years ago
  • Comments: 15 (7 by maintainers)

Most upvoted comments

I just put together a minimal example - the kicker… it works as expected! I’ll keep investigating as to why it doesn’t work in my full react app.

In my full app if i don’t “fork” it works. I think i’ll just not fork.

import fetch from 'node-fetch';
import {createStore, applyMiddleware, compose, combineReducers} from "redux";
import createSagaMiddleware, { delay, END } from 'redux-saga';
import { apiMiddleware,CALL_API } from 'redux-api-middleware';
import { all, race, take, put, call, fork, select, takeEvery, takeLatest, takeFirst, actionChannel, cancelled, throttle } from 'redux-saga/effects';

// Action

function createAction() {
	return {
		[CALL_API]: {
			endpoint: '/create',
			fetch: () => {
				return fetch("https://www.google.com");
			},
			method: 'GET',
			body: {},
			types: [
				{
					type: "CREATING",
					payload: {some_data_for_ui_update:1}
				},
				"CREATED",
				"CREATE_FAILED",
			],
		}
	};
}

// Saga

function * createActionResource(data) {
	yield put(createAction());
	yield call(delay,3000);
}


function * createActionSaga(action) {
	yield fork(createActionResource, {});
	//yield put(createAction());
console.log("OK WAITING FOR RACE");
	const response = yield race({
		success: take("CREATED"),
		fail: take("CREATE_FAILED"),
	});

	console.log("ANTYHING AFTER FORK???", response);
}

export function* watchCreateAction() {
	yield takeEvery("CREATE_ACTION", createActionSaga);
}

function * rootSaga() {
	yield all([
		watchCreateAction(),
	]);
}

// Reducer

const reducer = (state = {}, {type, payload}) => {
	console.log("in reducer:", type, payload);

	return state;
}

const rootReducer = combineReducers({
    reducer,
});

// Store

const sagaMiddleware = createSagaMiddleware();

const middlewares = [
	apiMiddleware,
	sagaMiddleware,
];
const middlewareEnhancer = applyMiddleware(...middlewares);

const storeEnhancers = [middlewareEnhancer];

const composedEnhancer = compose(...storeEnhancers);

const store = createStore(
	rootReducer,
	undefined,
	composedEnhancer
);

store.runSaga = sagaMiddleware.run;
store.runSaga(rootSaga);


store.dispatch({
	type: "CREATE_ACTION"
});