Saga always cancelled
up vote
1
down vote
favorite
I use redux-saga and have the following code:
function* loginFlow(username, password) {
try {
yield call(loginApi, username, password);
yield put({ type: LOGIN_SUCCESS });
yield put({ type: TOGGLE_LOGGED_DONE, payload: true });
yield put(push('/dashboard'));
} catch (error) {
yield put({ type: LOGIN_ERROR, error });
} finally {
if (yield cancelled()) {
console.log('ALWAYS CANCELLED');
// yield put(replace('/login'));
}
}
}
// Watcher saga.
function* loginWatcher() {
while (true) {
const { username, password } = yield take(LOGIN_REQUESTING);
const task = yield fork(loginFlow, username, password);
const action = yield take([LOGOUT, LOGIN_ERROR]);
if (action.type === LOGOUT) yield cancel(task);
yield call(logoutUser);
}
}
The problem is that the loginFlow
function always get cancelled in the end (I see 'ALWAYS CANCELLED'
in console). Even if I remove const action = yield take([LOGOUT, LOGIN_ERROR]);
and yield call(logoutUser);
from loginWatcher
.
I can't see that either LOGOUT
or LOGIN_ERROR
are fired:
Any ideas what wrong with my code?
Note that I use withRouter
in the index.js for login page where saga above is (else I get blank screen when redirect):
const withSaga = injectSaga({ key: 'login', saga });
export default compose( withReducer, withSaga, withConnect, )(LoginPage);
Best Regards
EDIT:
If wrapping loginWatcher
in try/catch
I also go to finally
there:
function* loginWatcher() {
while (true) {
try {
const { username, password } = yield take(LOGIN_REQUESTING);
const task = yield fork(loginFlow, username, password);
const action = yield take([LOGOUT, LOGIN_ERROR]);
if (action.type === LOGOUT) yield cancel(task);
yield call(logoutUser);
} catch (error) {
yield put({ type: LOGIN_ERROR, error });
} finally {
if (yield cancelled()) {
console.log('HERE AS WELL');
// yield put(push('/login'));
}
}
}
}
redux-saga
|
show 3 more comments
up vote
1
down vote
favorite
I use redux-saga and have the following code:
function* loginFlow(username, password) {
try {
yield call(loginApi, username, password);
yield put({ type: LOGIN_SUCCESS });
yield put({ type: TOGGLE_LOGGED_DONE, payload: true });
yield put(push('/dashboard'));
} catch (error) {
yield put({ type: LOGIN_ERROR, error });
} finally {
if (yield cancelled()) {
console.log('ALWAYS CANCELLED');
// yield put(replace('/login'));
}
}
}
// Watcher saga.
function* loginWatcher() {
while (true) {
const { username, password } = yield take(LOGIN_REQUESTING);
const task = yield fork(loginFlow, username, password);
const action = yield take([LOGOUT, LOGIN_ERROR]);
if (action.type === LOGOUT) yield cancel(task);
yield call(logoutUser);
}
}
The problem is that the loginFlow
function always get cancelled in the end (I see 'ALWAYS CANCELLED'
in console). Even if I remove const action = yield take([LOGOUT, LOGIN_ERROR]);
and yield call(logoutUser);
from loginWatcher
.
I can't see that either LOGOUT
or LOGIN_ERROR
are fired:
Any ideas what wrong with my code?
Note that I use withRouter
in the index.js for login page where saga above is (else I get blank screen when redirect):
const withSaga = injectSaga({ key: 'login', saga });
export default compose( withReducer, withSaga, withConnect, )(LoginPage);
Best Regards
EDIT:
If wrapping loginWatcher
in try/catch
I also go to finally
there:
function* loginWatcher() {
while (true) {
try {
const { username, password } = yield take(LOGIN_REQUESTING);
const task = yield fork(loginFlow, username, password);
const action = yield take([LOGOUT, LOGIN_ERROR]);
if (action.type === LOGOUT) yield cancel(task);
yield call(logoutUser);
} catch (error) {
yield put({ type: LOGIN_ERROR, error });
} finally {
if (yield cancelled()) {
console.log('HERE AS WELL');
// yield put(push('/login'));
}
}
}
}
redux-saga
WraploginWatcher()
in atry { ... } finally { if (yield cancelled()) { ... } }
. I suspect it gets cancelled too.
– Andrey Moiseev
Nov 9 at 13:46
@AndreyMoiseev Did you mean like my edit? Go to finally there as well with try/catch...
– user1665355
Nov 9 at 14:28
@AndreyMoiseev Seems to be something withyield cancelled()
, it's always true...
– user1665355
Nov 9 at 14:29
In redux-saga, allfork
ed andcall
ed sagas are cancelled recursively. Something in your code is cancellingloginWatcher()
, which in its turn recursively cancelsloginFlow()
. I suspect two things: 1) the code where you startloginWatcher()
cancels it, 2)yield put(push('/dashboard'))
cases a side effect somewhere in your code, and cancels it.
– Andrey Moiseev
Nov 9 at 14:55
Please add the code where you startloginWatcher()
, and the code where you handleLOCATION_CHANGE
. Also, check out this question. Probably you have code that cancels sagas onLOCATION_CHANGE
.
– Andrey Moiseev
Nov 9 at 14:58
|
show 3 more comments
up vote
1
down vote
favorite
up vote
1
down vote
favorite
I use redux-saga and have the following code:
function* loginFlow(username, password) {
try {
yield call(loginApi, username, password);
yield put({ type: LOGIN_SUCCESS });
yield put({ type: TOGGLE_LOGGED_DONE, payload: true });
yield put(push('/dashboard'));
} catch (error) {
yield put({ type: LOGIN_ERROR, error });
} finally {
if (yield cancelled()) {
console.log('ALWAYS CANCELLED');
// yield put(replace('/login'));
}
}
}
// Watcher saga.
function* loginWatcher() {
while (true) {
const { username, password } = yield take(LOGIN_REQUESTING);
const task = yield fork(loginFlow, username, password);
const action = yield take([LOGOUT, LOGIN_ERROR]);
if (action.type === LOGOUT) yield cancel(task);
yield call(logoutUser);
}
}
The problem is that the loginFlow
function always get cancelled in the end (I see 'ALWAYS CANCELLED'
in console). Even if I remove const action = yield take([LOGOUT, LOGIN_ERROR]);
and yield call(logoutUser);
from loginWatcher
.
I can't see that either LOGOUT
or LOGIN_ERROR
are fired:
Any ideas what wrong with my code?
Note that I use withRouter
in the index.js for login page where saga above is (else I get blank screen when redirect):
const withSaga = injectSaga({ key: 'login', saga });
export default compose( withReducer, withSaga, withConnect, )(LoginPage);
Best Regards
EDIT:
If wrapping loginWatcher
in try/catch
I also go to finally
there:
function* loginWatcher() {
while (true) {
try {
const { username, password } = yield take(LOGIN_REQUESTING);
const task = yield fork(loginFlow, username, password);
const action = yield take([LOGOUT, LOGIN_ERROR]);
if (action.type === LOGOUT) yield cancel(task);
yield call(logoutUser);
} catch (error) {
yield put({ type: LOGIN_ERROR, error });
} finally {
if (yield cancelled()) {
console.log('HERE AS WELL');
// yield put(push('/login'));
}
}
}
}
redux-saga
I use redux-saga and have the following code:
function* loginFlow(username, password) {
try {
yield call(loginApi, username, password);
yield put({ type: LOGIN_SUCCESS });
yield put({ type: TOGGLE_LOGGED_DONE, payload: true });
yield put(push('/dashboard'));
} catch (error) {
yield put({ type: LOGIN_ERROR, error });
} finally {
if (yield cancelled()) {
console.log('ALWAYS CANCELLED');
// yield put(replace('/login'));
}
}
}
// Watcher saga.
function* loginWatcher() {
while (true) {
const { username, password } = yield take(LOGIN_REQUESTING);
const task = yield fork(loginFlow, username, password);
const action = yield take([LOGOUT, LOGIN_ERROR]);
if (action.type === LOGOUT) yield cancel(task);
yield call(logoutUser);
}
}
The problem is that the loginFlow
function always get cancelled in the end (I see 'ALWAYS CANCELLED'
in console). Even if I remove const action = yield take([LOGOUT, LOGIN_ERROR]);
and yield call(logoutUser);
from loginWatcher
.
I can't see that either LOGOUT
or LOGIN_ERROR
are fired:
Any ideas what wrong with my code?
Note that I use withRouter
in the index.js for login page where saga above is (else I get blank screen when redirect):
const withSaga = injectSaga({ key: 'login', saga });
export default compose( withReducer, withSaga, withConnect, )(LoginPage);
Best Regards
EDIT:
If wrapping loginWatcher
in try/catch
I also go to finally
there:
function* loginWatcher() {
while (true) {
try {
const { username, password } = yield take(LOGIN_REQUESTING);
const task = yield fork(loginFlow, username, password);
const action = yield take([LOGOUT, LOGIN_ERROR]);
if (action.type === LOGOUT) yield cancel(task);
yield call(logoutUser);
} catch (error) {
yield put({ type: LOGIN_ERROR, error });
} finally {
if (yield cancelled()) {
console.log('HERE AS WELL');
// yield put(push('/login'));
}
}
}
}
redux-saga
redux-saga
edited Nov 9 at 15:30
asked Nov 9 at 10:27
user1665355
99652350
99652350
WraploginWatcher()
in atry { ... } finally { if (yield cancelled()) { ... } }
. I suspect it gets cancelled too.
– Andrey Moiseev
Nov 9 at 13:46
@AndreyMoiseev Did you mean like my edit? Go to finally there as well with try/catch...
– user1665355
Nov 9 at 14:28
@AndreyMoiseev Seems to be something withyield cancelled()
, it's always true...
– user1665355
Nov 9 at 14:29
In redux-saga, allfork
ed andcall
ed sagas are cancelled recursively. Something in your code is cancellingloginWatcher()
, which in its turn recursively cancelsloginFlow()
. I suspect two things: 1) the code where you startloginWatcher()
cancels it, 2)yield put(push('/dashboard'))
cases a side effect somewhere in your code, and cancels it.
– Andrey Moiseev
Nov 9 at 14:55
Please add the code where you startloginWatcher()
, and the code where you handleLOCATION_CHANGE
. Also, check out this question. Probably you have code that cancels sagas onLOCATION_CHANGE
.
– Andrey Moiseev
Nov 9 at 14:58
|
show 3 more comments
WraploginWatcher()
in atry { ... } finally { if (yield cancelled()) { ... } }
. I suspect it gets cancelled too.
– Andrey Moiseev
Nov 9 at 13:46
@AndreyMoiseev Did you mean like my edit? Go to finally there as well with try/catch...
– user1665355
Nov 9 at 14:28
@AndreyMoiseev Seems to be something withyield cancelled()
, it's always true...
– user1665355
Nov 9 at 14:29
In redux-saga, allfork
ed andcall
ed sagas are cancelled recursively. Something in your code is cancellingloginWatcher()
, which in its turn recursively cancelsloginFlow()
. I suspect two things: 1) the code where you startloginWatcher()
cancels it, 2)yield put(push('/dashboard'))
cases a side effect somewhere in your code, and cancels it.
– Andrey Moiseev
Nov 9 at 14:55
Please add the code where you startloginWatcher()
, and the code where you handleLOCATION_CHANGE
. Also, check out this question. Probably you have code that cancels sagas onLOCATION_CHANGE
.
– Andrey Moiseev
Nov 9 at 14:58
Wrap
loginWatcher()
in a try { ... } finally { if (yield cancelled()) { ... } }
. I suspect it gets cancelled too.– Andrey Moiseev
Nov 9 at 13:46
Wrap
loginWatcher()
in a try { ... } finally { if (yield cancelled()) { ... } }
. I suspect it gets cancelled too.– Andrey Moiseev
Nov 9 at 13:46
@AndreyMoiseev Did you mean like my edit? Go to finally there as well with try/catch...
– user1665355
Nov 9 at 14:28
@AndreyMoiseev Did you mean like my edit? Go to finally there as well with try/catch...
– user1665355
Nov 9 at 14:28
@AndreyMoiseev Seems to be something with
yield cancelled()
, it's always true...– user1665355
Nov 9 at 14:29
@AndreyMoiseev Seems to be something with
yield cancelled()
, it's always true...– user1665355
Nov 9 at 14:29
In redux-saga, all
fork
ed and call
ed sagas are cancelled recursively. Something in your code is cancelling loginWatcher()
, which in its turn recursively cancels loginFlow()
. I suspect two things: 1) the code where you start loginWatcher()
cancels it, 2) yield put(push('/dashboard'))
cases a side effect somewhere in your code, and cancels it.– Andrey Moiseev
Nov 9 at 14:55
In redux-saga, all
fork
ed and call
ed sagas are cancelled recursively. Something in your code is cancelling loginWatcher()
, which in its turn recursively cancels loginFlow()
. I suspect two things: 1) the code where you start loginWatcher()
cancels it, 2) yield put(push('/dashboard'))
cases a side effect somewhere in your code, and cancels it.– Andrey Moiseev
Nov 9 at 14:55
Please add the code where you start
loginWatcher()
, and the code where you handle LOCATION_CHANGE
. Also, check out this question. Probably you have code that cancels sagas on LOCATION_CHANGE
.– Andrey Moiseev
Nov 9 at 14:58
Please add the code where you start
loginWatcher()
, and the code where you handle LOCATION_CHANGE
. Also, check out this question. Probably you have code that cancels sagas on LOCATION_CHANGE
.– Andrey Moiseev
Nov 9 at 14:58
|
show 3 more comments
1 Answer
1
active
oldest
votes
up vote
1
down vote
accepted
I'm posting what we've gathered as an answer, so that this question is useful for future readers.
In redux-saga, sagas started via call()
and fork()
are cancelled recursively. Saga means a recursively cancellable task. So when a saga gets cancelled, you should check its parent saga, and so on.
This code snippet you've posted:
const withSaga = injectSaga({ key: 'login', saga });
export default compose( withReducer, withSaga, withConnect, )(LoginPage)
Google suggests that it uses this redux-saga + react-boilerplate example. It covers cancellation and how to disable it. Check the link to find out about it.
I'm not familiar with react-boilerplate (React ecosystem is huge), but I guess my answer at least narrows down the search. Consider asking a separate question with react-boilerplate if you get confused.
Thank you! What works is to move saga to global scope. Then it is not cancelled during route change!
– user1665355
Nov 10 at 15:43
add a comment |
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
1
down vote
accepted
I'm posting what we've gathered as an answer, so that this question is useful for future readers.
In redux-saga, sagas started via call()
and fork()
are cancelled recursively. Saga means a recursively cancellable task. So when a saga gets cancelled, you should check its parent saga, and so on.
This code snippet you've posted:
const withSaga = injectSaga({ key: 'login', saga });
export default compose( withReducer, withSaga, withConnect, )(LoginPage)
Google suggests that it uses this redux-saga + react-boilerplate example. It covers cancellation and how to disable it. Check the link to find out about it.
I'm not familiar with react-boilerplate (React ecosystem is huge), but I guess my answer at least narrows down the search. Consider asking a separate question with react-boilerplate if you get confused.
Thank you! What works is to move saga to global scope. Then it is not cancelled during route change!
– user1665355
Nov 10 at 15:43
add a comment |
up vote
1
down vote
accepted
I'm posting what we've gathered as an answer, so that this question is useful for future readers.
In redux-saga, sagas started via call()
and fork()
are cancelled recursively. Saga means a recursively cancellable task. So when a saga gets cancelled, you should check its parent saga, and so on.
This code snippet you've posted:
const withSaga = injectSaga({ key: 'login', saga });
export default compose( withReducer, withSaga, withConnect, )(LoginPage)
Google suggests that it uses this redux-saga + react-boilerplate example. It covers cancellation and how to disable it. Check the link to find out about it.
I'm not familiar with react-boilerplate (React ecosystem is huge), but I guess my answer at least narrows down the search. Consider asking a separate question with react-boilerplate if you get confused.
Thank you! What works is to move saga to global scope. Then it is not cancelled during route change!
– user1665355
Nov 10 at 15:43
add a comment |
up vote
1
down vote
accepted
up vote
1
down vote
accepted
I'm posting what we've gathered as an answer, so that this question is useful for future readers.
In redux-saga, sagas started via call()
and fork()
are cancelled recursively. Saga means a recursively cancellable task. So when a saga gets cancelled, you should check its parent saga, and so on.
This code snippet you've posted:
const withSaga = injectSaga({ key: 'login', saga });
export default compose( withReducer, withSaga, withConnect, )(LoginPage)
Google suggests that it uses this redux-saga + react-boilerplate example. It covers cancellation and how to disable it. Check the link to find out about it.
I'm not familiar with react-boilerplate (React ecosystem is huge), but I guess my answer at least narrows down the search. Consider asking a separate question with react-boilerplate if you get confused.
I'm posting what we've gathered as an answer, so that this question is useful for future readers.
In redux-saga, sagas started via call()
and fork()
are cancelled recursively. Saga means a recursively cancellable task. So when a saga gets cancelled, you should check its parent saga, and so on.
This code snippet you've posted:
const withSaga = injectSaga({ key: 'login', saga });
export default compose( withReducer, withSaga, withConnect, )(LoginPage)
Google suggests that it uses this redux-saga + react-boilerplate example. It covers cancellation and how to disable it. Check the link to find out about it.
I'm not familiar with react-boilerplate (React ecosystem is huge), but I guess my answer at least narrows down the search. Consider asking a separate question with react-boilerplate if you get confused.
answered Nov 9 at 15:47
Andrey Moiseev
1,34642745
1,34642745
Thank you! What works is to move saga to global scope. Then it is not cancelled during route change!
– user1665355
Nov 10 at 15:43
add a comment |
Thank you! What works is to move saga to global scope. Then it is not cancelled during route change!
– user1665355
Nov 10 at 15:43
Thank you! What works is to move saga to global scope. Then it is not cancelled during route change!
– user1665355
Nov 10 at 15:43
Thank you! What works is to move saga to global scope. Then it is not cancelled during route change!
– user1665355
Nov 10 at 15:43
add a comment |
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53223958%2fsaga-always-cancelled%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Wrap
loginWatcher()
in atry { ... } finally { if (yield cancelled()) { ... } }
. I suspect it gets cancelled too.– Andrey Moiseev
Nov 9 at 13:46
@AndreyMoiseev Did you mean like my edit? Go to finally there as well with try/catch...
– user1665355
Nov 9 at 14:28
@AndreyMoiseev Seems to be something with
yield cancelled()
, it's always true...– user1665355
Nov 9 at 14:29
In redux-saga, all
fork
ed andcall
ed sagas are cancelled recursively. Something in your code is cancellingloginWatcher()
, which in its turn recursively cancelsloginFlow()
. I suspect two things: 1) the code where you startloginWatcher()
cancels it, 2)yield put(push('/dashboard'))
cases a side effect somewhere in your code, and cancels it.– Andrey Moiseev
Nov 9 at 14:55
Please add the code where you start
loginWatcher()
, and the code where you handleLOCATION_CHANGE
. Also, check out this question. Probably you have code that cancels sagas onLOCATION_CHANGE
.– Andrey Moiseev
Nov 9 at 14:58