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;








5















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?










share|improve this question






















  • 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_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





    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

















5















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?










share|improve this question






















  • 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_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





    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













5












5








5








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?










share|improve this question














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






share|improve this question













share|improve this question











share|improve this question




share|improve this question










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 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





    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











  • 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






  • 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












2 Answers
2






active

oldest

votes


















3














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 catch statement.

  • 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 );







share|improve this answer
































    -1














    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).






    share|improve this answer























      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
      );



      );













      draft saved

      draft discarded


















      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









      3














      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 catch statement.

      • 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 );







      share|improve this answer





























        3














        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 catch statement.

        • 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 );







        share|improve this answer



























          3












          3








          3







          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 catch statement.

          • 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 );







          share|improve this answer















          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 catch statement.

          • 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 );








          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Mar 9 at 22:08

























          answered Mar 9 at 2:42









          victor.javictor.ja

          484315




          484315























              -1














              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).






              share|improve this answer



























                -1














                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).






                share|improve this answer

























                  -1












                  -1








                  -1







                  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).






                  share|improve this answer













                  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).







                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Mar 9 at 0:53









                  MarkusMarkus

                  1,21311230




                  1,21311230



























                      draft saved

                      draft discarded
















































                      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.




                      draft saved


                      draft discarded














                      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





















































                      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







                      Popular posts from this blog

                      AWS Lex not identifying response if by a variable The 2019 Stack Overflow Developer Survey Results Are In Announcing the arrival of Valued Associate #679: Cesar Manara Planned maintenance scheduled April 17/18, 2019 at 00:00UTC (8:00pm US/Eastern) The Ask Question Wizard is Live! Data science time! April 2019 and salary with experienceEnforcing custom enumeration in AWS LEX for slot valuesHow to give response based on user response in Amazon Lex?Intercepting AWS Lambda Response to a AWS Lex QueryLex chat bot error: Reached second execution of fulfillment lambda on the same utteranceamazon lex showing invalid responseLambda response send back to Lex slot?Response card in Amazon lexAmazon Lex - Lambda response return HTML to botHow can I solve 424 (Failed Dependency) (python) obtained from Amazon lex?

                      Алба-Юлія

                      Захаров Федір Захарович