Reputation: 2174
Our app uses an ATTEMPT - SUCCESS - FAILURE approach to handling our responses from the server.
I have a generator function that needs to behave like this:
function * getSingleSectorAttempt(action) {
const sectors = yield select(getSectors);
if (!sectors) {
//If there are no sectors, I need to call the GET_SECTORS_ATTEMPT action
//and only restart/continue this saga when the GET_SECTORS_SUCCESS action is fired
}
const id = sectors[action.name].id;
try {
const response = yield call(api.getSector, id);
//...
} catch (err) {
//...
}
}
From what I've read of the Redux Saga documentation, this does not seem immediately possible. However, I would like to see if I'm missing something. I've already tried this:
yield fork(takeLatest, Type.GET_SECTORS_SUCCESS, getSingleSectorAttempt);
yield put(Actions.getSectorsAttempt());
in the if(!sectors)
conditional block, but while this works it does not persist the initial GET_SINGLE_SECTOR_ATTEMPT
action parameters, and I am not sure how to get it to do so without getting into callback and argument spaghetti.
Upvotes: 0
Views: 623
Reputation: 5155
The effect allowing you to wait for an action to be dispatched is take
. In your case:
function* getSingleSectorAttempt(action) {
let sectors = yield select(getSectors);
if (!sectors) {
yield put(getSectorsAttempt());
yield take(GET_SECTORS_SUCCESS);
sectors = yield select(getSectors);
}
// resume here as normal
}
Your own answer could have unexpected side-effects. For example, if getSectors
can return a falsy value several times in the lifetime of the app, you would have several forked processes waiting for GET_SECTORS_SUCCESS
to be dispatched, and each executing your side-effect, each keeping a reference to the action that triggered it.
Upvotes: 1
Reputation: 2174
Oops, figured it out:
function* getSingleSectorAttempt(action) {
const sectors = yield select(getSectors);
if(!sectors){
//Pass initial action in a callback function like so:
yield fork(takeLatest, Type.GET_SECTORS_SUCCESS, () => getSingleSectorAttempt(action));
yield put(Actions.getSectorsAttempt());
} else {
const id = sectors[action.name].id;
try {
const response = yield call(api.getSector, id);
//...
} catch (err) {
//..
}
}
}
Upvotes: 0