Where should the response logic happen, in the saga or the reducer? Announcing the arrival of Valued Associate #679: Cesar Manara Planned maintenance scheduled April 23, 2019 at 00:00UTC (8:00pm US/Eastern) Data science time! April 2019 and salary with experience The Ask Question Wizard is Live!Where should I put <script> tags in HTML markup?redux-thunk dispatch method fires undefined actionHow to write log in logic in redux?takeLatestHelper has been cancelled in redux-saga-effectsRedux. Putting most of logic in ActionCreators for decreasing reducer overheadsBest practice for updating individual state properties with Redux SagaRedux state resets after next action dispatchRedux - mapDispatchToProps - TypeError: _this.props.setCurrentUserHandle is not a functionRedux-Saga somehow reducer updates without going through the sagaWhat is the best place to put pure and synchronous logic while using React with Redux and Redux-Saga?
Can an alien society believe that their star system is the universe?
AppleTVs create a chatty alternate WiFi network
Sum letters are not two different
Why wasn't DOSKEY integrated with COMMAND.COM?
Disembodied hand growing fangs
Illegal assignment from sObject to Id
How can I reduce the gap between left and right of cdot with a macro?
Combinatorics problem on counting.
Take 2! Is this homebrew Lady of Pain warlock patron balanced?
Central Vacuuming: Is it worth it, and how does it compare to normal vacuuming?
If Windows 7 doesn't support WSL, then what does Linux subsystem option mean?
Selecting user stories during sprint planning
Why aren't air breathing engines used as small first stages?
NumericArray versus PackedArray in MMA12
Is there any word for a place full of confusion?
As a beginner, should I get a Squier Strat with a SSS config or a HSS?
What is the topology associated with the algebras for the ultrafilter monad?
What do you call the main part of a joke?
Crossing US/Canada Border for less than 24 hours
Chinese Seal on silk painting - what does it mean?
Is there a kind of relay only consumes power when switching?
What's the meaning of "fortified infraction restraint"?
Project Euler #1 in C++
Is it fair for a professor to grade us on the possession of past papers?
Where should the response logic happen, in the saga or the reducer?
Announcing the arrival of Valued Associate #679: Cesar Manara
Planned maintenance scheduled April 23, 2019 at 00:00UTC (8:00pm US/Eastern)
Data science time! April 2019 and salary with experience
The Ask Question Wizard is Live!Where should I put <script> tags in HTML markup?redux-thunk dispatch method fires undefined actionHow to write log in logic in redux?takeLatestHelper has been cancelled in redux-saga-effectsRedux. Putting most of logic in ActionCreators for decreasing reducer overheadsBest practice for updating individual state properties with Redux SagaRedux state resets after next action dispatchRedux - mapDispatchToProps - TypeError: _this.props.setCurrentUserHandle is not a functionRedux-Saga somehow reducer updates without going through the sagaWhat is the best place to put pure and synchronous logic while using React with Redux and Redux-Saga?
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty height:90px;width:728px;box-sizing:border-box;
Let's say I have a saga that looks so:
export function* incrementAsync(action)
try
const res = yield call(Api.signin.create, action.payload);
yield put(
type: USER_SIGN_IN_FETCH_SUCCESS,
payload: res.data.auth
;
catch (e)
yield put( type: USER_SIGN_IN_FETCH_ERROR_NETWORK );
The fech was a success, but that doesn't mean that the user was actually logged in:
res.data.auth.error could be true
My question is whether I should do things like:
if (//user was succesfully logged in)
yield put(//user was successfully logged in)
else if //wrong username
yield put(//wrong username)
else if //wrong password
yield put(//wrong password)
Or should I have only one for success and one for error, and in the reducer analyze the logic and build the store relative to the response data?
javascript reactjs redux redux-saga
|
show 6 more comments
Let's say I have a saga that looks so:
export function* incrementAsync(action)
try
const res = yield call(Api.signin.create, action.payload);
yield put(
type: USER_SIGN_IN_FETCH_SUCCESS,
payload: res.data.auth
;
catch (e)
yield put( type: USER_SIGN_IN_FETCH_ERROR_NETWORK );
The fech was a success, but that doesn't mean that the user was actually logged in:
res.data.auth.error could be true
My question is whether I should do things like:
if (//user was succesfully logged in)
yield put(//user was successfully logged in)
else if //wrong username
yield put(//wrong username)
else if //wrong password
yield put(//wrong password)
Or should I have only one for success and one for error, and in the reducer analyze the logic and build the store relative to the response data?
javascript reactjs redux redux-saga
Reducers only job is to change the state according to an action. You should design meaningful actions that trigger predictable state changes.
– Emile Bergeron
Mar 8 at 20:30
Ok, perfect, but that means all the logic goes in the saga generator function?
– Trufa
Mar 8 at 20:34
Yes, because theUSER_SIGN_IN_FETCH_SUCCESSonly makes sense if there's some kind of loading animation going on, since it's not necessarily a login success. The saga should yield meaningful actions, so your whole logic is clearer, and easier to debug through the Redux dev tools.
– Emile Bergeron
Mar 8 at 20:43
1
This is about reducers vs action creators but is just as valid for sagas: redux.js.org/faq/…
– Martin Kadlec
Mar 8 at 20:48
Personally if there is extractable logic you need to do I prefer to put it into a utility file. Then you can import it in reducer or saga based on your needs and it won't affect your code much either way.
– Martin Kadlec
Mar 8 at 20:50
|
show 6 more comments
Let's say I have a saga that looks so:
export function* incrementAsync(action)
try
const res = yield call(Api.signin.create, action.payload);
yield put(
type: USER_SIGN_IN_FETCH_SUCCESS,
payload: res.data.auth
;
catch (e)
yield put( type: USER_SIGN_IN_FETCH_ERROR_NETWORK );
The fech was a success, but that doesn't mean that the user was actually logged in:
res.data.auth.error could be true
My question is whether I should do things like:
if (//user was succesfully logged in)
yield put(//user was successfully logged in)
else if //wrong username
yield put(//wrong username)
else if //wrong password
yield put(//wrong password)
Or should I have only one for success and one for error, and in the reducer analyze the logic and build the store relative to the response data?
javascript reactjs redux redux-saga
Let's say I have a saga that looks so:
export function* incrementAsync(action)
try
const res = yield call(Api.signin.create, action.payload);
yield put(
type: USER_SIGN_IN_FETCH_SUCCESS,
payload: res.data.auth
;
catch (e)
yield put( type: USER_SIGN_IN_FETCH_ERROR_NETWORK );
The fech was a success, but that doesn't mean that the user was actually logged in:
res.data.auth.error could be true
My question is whether I should do things like:
if (//user was succesfully logged in)
yield put(//user was successfully logged in)
else if //wrong username
yield put(//wrong username)
else if //wrong password
yield put(//wrong password)
Or should I have only one for success and one for error, and in the reducer analyze the logic and build the store relative to the response data?
javascript reactjs redux redux-saga
javascript reactjs redux redux-saga
asked Mar 8 at 20:17
TrufaTrufa
19.1k34110169
19.1k34110169
Reducers only job is to change the state according to an action. You should design meaningful actions that trigger predictable state changes.
– Emile Bergeron
Mar 8 at 20:30
Ok, perfect, but that means all the logic goes in the saga generator function?
– Trufa
Mar 8 at 20:34
Yes, because theUSER_SIGN_IN_FETCH_SUCCESSonly makes sense if there's some kind of loading animation going on, since it's not necessarily a login success. The saga should yield meaningful actions, so your whole logic is clearer, and easier to debug through the Redux dev tools.
– Emile Bergeron
Mar 8 at 20:43
1
This is about reducers vs action creators but is just as valid for sagas: redux.js.org/faq/…
– Martin Kadlec
Mar 8 at 20:48
Personally if there is extractable logic you need to do I prefer to put it into a utility file. Then you can import it in reducer or saga based on your needs and it won't affect your code much either way.
– Martin Kadlec
Mar 8 at 20:50
|
show 6 more comments
Reducers only job is to change the state according to an action. You should design meaningful actions that trigger predictable state changes.
– Emile Bergeron
Mar 8 at 20:30
Ok, perfect, but that means all the logic goes in the saga generator function?
– Trufa
Mar 8 at 20:34
Yes, because theUSER_SIGN_IN_FETCH_SUCCESSonly makes sense if there's some kind of loading animation going on, since it's not necessarily a login success. The saga should yield meaningful actions, so your whole logic is clearer, and easier to debug through the Redux dev tools.
– Emile Bergeron
Mar 8 at 20:43
1
This is about reducers vs action creators but is just as valid for sagas: redux.js.org/faq/…
– Martin Kadlec
Mar 8 at 20:48
Personally if there is extractable logic you need to do I prefer to put it into a utility file. Then you can import it in reducer or saga based on your needs and it won't affect your code much either way.
– Martin Kadlec
Mar 8 at 20:50
Reducers only job is to change the state according to an action. You should design meaningful actions that trigger predictable state changes.
– Emile Bergeron
Mar 8 at 20:30
Reducers only job is to change the state according to an action. You should design meaningful actions that trigger predictable state changes.
– Emile Bergeron
Mar 8 at 20:30
Ok, perfect, but that means all the logic goes in the saga generator function?
– Trufa
Mar 8 at 20:34
Ok, perfect, but that means all the logic goes in the saga generator function?
– Trufa
Mar 8 at 20:34
Yes, because the
USER_SIGN_IN_FETCH_SUCCESS only makes sense if there's some kind of loading animation going on, since it's not necessarily a login success. The saga should yield meaningful actions, so your whole logic is clearer, and easier to debug through the Redux dev tools.– Emile Bergeron
Mar 8 at 20:43
Yes, because the
USER_SIGN_IN_FETCH_SUCCESS only makes sense if there's some kind of loading animation going on, since it's not necessarily a login success. The saga should yield meaningful actions, so your whole logic is clearer, and easier to debug through the Redux dev tools.– Emile Bergeron
Mar 8 at 20:43
1
1
This is about reducers vs action creators but is just as valid for sagas: redux.js.org/faq/…
– Martin Kadlec
Mar 8 at 20:48
This is about reducers vs action creators but is just as valid for sagas: redux.js.org/faq/…
– Martin Kadlec
Mar 8 at 20:48
Personally if there is extractable logic you need to do I prefer to put it into a utility file. Then you can import it in reducer or saga based on your needs and it won't affect your code much either way.
– Martin Kadlec
Mar 8 at 20:50
Personally if there is extractable logic you need to do I prefer to put it into a utility file. Then you can import it in reducer or saga based on your needs and it won't affect your code much either way.
– Martin Kadlec
Mar 8 at 20:50
|
show 6 more comments
2 Answers
2
active
oldest
votes
Error logic should always be handled at sagas.
In this particular case your API is not throwing a correct error because if your API call was not a success (200, for example), that logic should be handled at your catch statement.
Why is this error not being handled there?
If you are using axios, this could happen as a consequence of a bad design of the API (i.e. returning 200 instead of 400 for an error in signin in).
If it's just you doing it by hand you should throw an error and handle that logic at catch in sagas.
So my recommendation is:
- Throw an error to the sagas to handle error logic at
catchstatement. If you have to parse the response in order to programmatically throw the error do it at the API layer if you can.
Make a specific action to handle the signup error OR just make a generic FAIL action and pass an error message to it(an then store it at redux to show it).
It should look something like:
export function* incrementAsync(action)
try
const res = yield call(Api.signin.create, action.payload);
yield put(
type: USER_SIGN_IN_FETCH_SUCCESS,
payload: res.data.auth
;
catch (error)
yield put( type: USER_SIGN_IN_FAIL, payload: error.message );
add a comment |
I'd always move as much logic as possible to the reducer.
Logic there is more visible in the dev tools, if you do it in the saga it can be harder.
It is also easier to test, as it's a synchronous and pure function.
Also, USER_SIGN_IN_FETCH_SUCCESS seems perfectly meaningful to me for an action send from saga to reducer (actions from components to reducer should be less technical).
add a comment |
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
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%2f55070426%2fwhere-should-the-response-logic-happen-in-the-saga-or-the-reducer%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
Error logic should always be handled at sagas.
In this particular case your API is not throwing a correct error because if your API call was not a success (200, for example), that logic should be handled at your catch statement.
Why is this error not being handled there?
If you are using axios, this could happen as a consequence of a bad design of the API (i.e. returning 200 instead of 400 for an error in signin in).
If it's just you doing it by hand you should throw an error and handle that logic at catch in sagas.
So my recommendation is:
- Throw an error to the sagas to handle error logic at
catchstatement. If you have to parse the response in order to programmatically throw the error do it at the API layer if you can.
Make a specific action to handle the signup error OR just make a generic FAIL action and pass an error message to it(an then store it at redux to show it).
It should look something like:
export function* incrementAsync(action)
try
const res = yield call(Api.signin.create, action.payload);
yield put(
type: USER_SIGN_IN_FETCH_SUCCESS,
payload: res.data.auth
;
catch (error)
yield put( type: USER_SIGN_IN_FAIL, payload: error.message );
add a comment |
Error logic should always be handled at sagas.
In this particular case your API is not throwing a correct error because if your API call was not a success (200, for example), that logic should be handled at your catch statement.
Why is this error not being handled there?
If you are using axios, this could happen as a consequence of a bad design of the API (i.e. returning 200 instead of 400 for an error in signin in).
If it's just you doing it by hand you should throw an error and handle that logic at catch in sagas.
So my recommendation is:
- Throw an error to the sagas to handle error logic at
catchstatement. If you have to parse the response in order to programmatically throw the error do it at the API layer if you can.
Make a specific action to handle the signup error OR just make a generic FAIL action and pass an error message to it(an then store it at redux to show it).
It should look something like:
export function* incrementAsync(action)
try
const res = yield call(Api.signin.create, action.payload);
yield put(
type: USER_SIGN_IN_FETCH_SUCCESS,
payload: res.data.auth
;
catch (error)
yield put( type: USER_SIGN_IN_FAIL, payload: error.message );
add a comment |
Error logic should always be handled at sagas.
In this particular case your API is not throwing a correct error because if your API call was not a success (200, for example), that logic should be handled at your catch statement.
Why is this error not being handled there?
If you are using axios, this could happen as a consequence of a bad design of the API (i.e. returning 200 instead of 400 for an error in signin in).
If it's just you doing it by hand you should throw an error and handle that logic at catch in sagas.
So my recommendation is:
- Throw an error to the sagas to handle error logic at
catchstatement. If you have to parse the response in order to programmatically throw the error do it at the API layer if you can.
Make a specific action to handle the signup error OR just make a generic FAIL action and pass an error message to it(an then store it at redux to show it).
It should look something like:
export function* incrementAsync(action)
try
const res = yield call(Api.signin.create, action.payload);
yield put(
type: USER_SIGN_IN_FETCH_SUCCESS,
payload: res.data.auth
;
catch (error)
yield put( type: USER_SIGN_IN_FAIL, payload: error.message );
Error logic should always be handled at sagas.
In this particular case your API is not throwing a correct error because if your API call was not a success (200, for example), that logic should be handled at your catch statement.
Why is this error not being handled there?
If you are using axios, this could happen as a consequence of a bad design of the API (i.e. returning 200 instead of 400 for an error in signin in).
If it's just you doing it by hand you should throw an error and handle that logic at catch in sagas.
So my recommendation is:
- Throw an error to the sagas to handle error logic at
catchstatement. If you have to parse the response in order to programmatically throw the error do it at the API layer if you can.
Make a specific action to handle the signup error OR just make a generic FAIL action and pass an error message to it(an then store it at redux to show it).
It should look something like:
export function* incrementAsync(action)
try
const res = yield call(Api.signin.create, action.payload);
yield put(
type: USER_SIGN_IN_FETCH_SUCCESS,
payload: res.data.auth
;
catch (error)
yield put( type: USER_SIGN_IN_FAIL, payload: error.message );
edited Mar 9 at 22:08
answered Mar 9 at 2:42
victor.javictor.ja
484315
484315
add a comment |
add a comment |
I'd always move as much logic as possible to the reducer.
Logic there is more visible in the dev tools, if you do it in the saga it can be harder.
It is also easier to test, as it's a synchronous and pure function.
Also, USER_SIGN_IN_FETCH_SUCCESS seems perfectly meaningful to me for an action send from saga to reducer (actions from components to reducer should be less technical).
add a comment |
I'd always move as much logic as possible to the reducer.
Logic there is more visible in the dev tools, if you do it in the saga it can be harder.
It is also easier to test, as it's a synchronous and pure function.
Also, USER_SIGN_IN_FETCH_SUCCESS seems perfectly meaningful to me for an action send from saga to reducer (actions from components to reducer should be less technical).
add a comment |
I'd always move as much logic as possible to the reducer.
Logic there is more visible in the dev tools, if you do it in the saga it can be harder.
It is also easier to test, as it's a synchronous and pure function.
Also, USER_SIGN_IN_FETCH_SUCCESS seems perfectly meaningful to me for an action send from saga to reducer (actions from components to reducer should be less technical).
I'd always move as much logic as possible to the reducer.
Logic there is more visible in the dev tools, if you do it in the saga it can be harder.
It is also easier to test, as it's a synchronous and pure function.
Also, USER_SIGN_IN_FETCH_SUCCESS seems perfectly meaningful to me for an action send from saga to reducer (actions from components to reducer should be less technical).
answered Mar 9 at 0:53
MarkusMarkus
1,21311230
1,21311230
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
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%2f55070426%2fwhere-should-the-response-logic-happen-in-the-saga-or-the-reducer%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
Reducers only job is to change the state according to an action. You should design meaningful actions that trigger predictable state changes.
– Emile Bergeron
Mar 8 at 20:30
Ok, perfect, but that means all the logic goes in the saga generator function?
– Trufa
Mar 8 at 20:34
Yes, because the
USER_SIGN_IN_FETCH_SUCCESSonly makes sense if there's some kind of loading animation going on, since it's not necessarily a login success. The saga should yield meaningful actions, so your whole logic is clearer, and easier to debug through the Redux dev tools.– Emile Bergeron
Mar 8 at 20:43
1
This is about reducers vs action creators but is just as valid for sagas: redux.js.org/faq/…
– Martin Kadlec
Mar 8 at 20:48
Personally if there is extractable logic you need to do I prefer to put it into a utility file. Then you can import it in reducer or saga based on your needs and it won't affect your code much either way.
– Martin Kadlec
Mar 8 at 20:50