How to achieve callbacks in Redux-Saga?
I think you should add redirect and alert to the login generator. This way all logic is in the saga and it is still easily tested. So basically your login saga would look like this:
function* login(action) {
try {
const state = yield select();
const token = state.authReducer.token;
const response = yield call(API.login,action.params,token);
yield put({type: ACTION_TYPES.LOGIN_SUCCESS, payload:response.data});
yield call(setItem,AUTH_STORAGE_KEY,response.data.api_token);
yield call(redirectToHomePage); // add this...
} catch (error) {
yield put({type: ACTION_TYPES.LOGIN_FAILURE, error});
yield call(alertError); // and this
}
}
You can simply work up by passing the extra info about your success and error callback functions into the payload itself. Since, redux pattern works in a quite decoupled manner.
this.props.actions.login({
credentials,
successCb: success => redirectToHomePage)
errorCb: error => alertError)
});
In the saga, you can deconstruct these callbacks from the payload and run them very easily based on your program flow.
I spent all day dinking around with this stuff, switching from thunk to redux-saga
I too have a lot of code that looks like this
this.props.actions.login(credentials)
.then((success)=>redirectToHomePage)
.catch((error)=>alertError);
its possible to use thunk + saga
function login(params) {
return (dispatch) => {
return new Promise((resolve, reject) => {
dispatch({
type: ACTION_TYPES.LOGIN_REQUEST,
params,
resolve,
reject
})
}
}
}
then over in saga land you can just do something like
function* login(action) {
let response = yourApi.request('http://www.urthing.com/login')
if (response.success) {
action.resolve(response.success) // or whatever
} else { action.reject() }
}