DRYing out my action creators











up vote
1
down vote

favorite
1












I've created a private function called _successResponse to handle successful responses from my promise.



The challenge was passing the dispatch function to the _successResponse which is being passed to the .then method as a callback.



I accomplished this by currying using .bind. I would love to get feedback on this approach.



import axios from 'axios';
import { browserHistory } from 'react-router';
import {
AUTH_USER,
AUTH_ERROR,
UNAUTH_USER,
FETCH_MESSAGE
} from './types';

const ROOT_URL = 'http://localhost:3090';

export function signinUser({ email, password }){
return function(dispatch){
// Submit email/password to server
axios.post(`${ROOT_URL}/signin`, { email, password })
.then(_successResponse.bind(null, dispatch))
.catch(() => {dispatch(authError('Bad Login Info'))})
}
}

export function signupUser({email, password}){
return function(dispatch){
axios.post(`${ROOT_URL}/signup`, { email, password })
.then(_successResponse.bind(null, dispatch))
.catch(response => {dispatch(authError(response.response.data.error))});
}
}

export function authError(error){
return {
type: AUTH_ERROR,
payload: error
}
}

export function signoutUser(){
localStorage.removeItem('token');

return { type: UNAUTH_USER }
}

export function fetchMessage(){
return function(dispatch){
axios.get(ROOT_URL, {
headers: { authorization: localStorage.getItem('token') }
})
.then(response => {
dispatch({
type: FETCH_MESSAGE,
payload: response.data.message
})
});
}
}

// Private functions
function _successResponse(dispatch, response){
// If request is valid...
// - Update state to indicate user is authenticated
dispatch({ type: AUTH_USER });
// - Save the JWT token
localStorage.setItem('token', response.data.token);
// - redirect to the route '/feature'
browserHistory.push('/feature');
}









share|improve this question




























    up vote
    1
    down vote

    favorite
    1












    I've created a private function called _successResponse to handle successful responses from my promise.



    The challenge was passing the dispatch function to the _successResponse which is being passed to the .then method as a callback.



    I accomplished this by currying using .bind. I would love to get feedback on this approach.



    import axios from 'axios';
    import { browserHistory } from 'react-router';
    import {
    AUTH_USER,
    AUTH_ERROR,
    UNAUTH_USER,
    FETCH_MESSAGE
    } from './types';

    const ROOT_URL = 'http://localhost:3090';

    export function signinUser({ email, password }){
    return function(dispatch){
    // Submit email/password to server
    axios.post(`${ROOT_URL}/signin`, { email, password })
    .then(_successResponse.bind(null, dispatch))
    .catch(() => {dispatch(authError('Bad Login Info'))})
    }
    }

    export function signupUser({email, password}){
    return function(dispatch){
    axios.post(`${ROOT_URL}/signup`, { email, password })
    .then(_successResponse.bind(null, dispatch))
    .catch(response => {dispatch(authError(response.response.data.error))});
    }
    }

    export function authError(error){
    return {
    type: AUTH_ERROR,
    payload: error
    }
    }

    export function signoutUser(){
    localStorage.removeItem('token');

    return { type: UNAUTH_USER }
    }

    export function fetchMessage(){
    return function(dispatch){
    axios.get(ROOT_URL, {
    headers: { authorization: localStorage.getItem('token') }
    })
    .then(response => {
    dispatch({
    type: FETCH_MESSAGE,
    payload: response.data.message
    })
    });
    }
    }

    // Private functions
    function _successResponse(dispatch, response){
    // If request is valid...
    // - Update state to indicate user is authenticated
    dispatch({ type: AUTH_USER });
    // - Save the JWT token
    localStorage.setItem('token', response.data.token);
    // - redirect to the route '/feature'
    browserHistory.push('/feature');
    }









    share|improve this question


























      up vote
      1
      down vote

      favorite
      1









      up vote
      1
      down vote

      favorite
      1






      1





      I've created a private function called _successResponse to handle successful responses from my promise.



      The challenge was passing the dispatch function to the _successResponse which is being passed to the .then method as a callback.



      I accomplished this by currying using .bind. I would love to get feedback on this approach.



      import axios from 'axios';
      import { browserHistory } from 'react-router';
      import {
      AUTH_USER,
      AUTH_ERROR,
      UNAUTH_USER,
      FETCH_MESSAGE
      } from './types';

      const ROOT_URL = 'http://localhost:3090';

      export function signinUser({ email, password }){
      return function(dispatch){
      // Submit email/password to server
      axios.post(`${ROOT_URL}/signin`, { email, password })
      .then(_successResponse.bind(null, dispatch))
      .catch(() => {dispatch(authError('Bad Login Info'))})
      }
      }

      export function signupUser({email, password}){
      return function(dispatch){
      axios.post(`${ROOT_URL}/signup`, { email, password })
      .then(_successResponse.bind(null, dispatch))
      .catch(response => {dispatch(authError(response.response.data.error))});
      }
      }

      export function authError(error){
      return {
      type: AUTH_ERROR,
      payload: error
      }
      }

      export function signoutUser(){
      localStorage.removeItem('token');

      return { type: UNAUTH_USER }
      }

      export function fetchMessage(){
      return function(dispatch){
      axios.get(ROOT_URL, {
      headers: { authorization: localStorage.getItem('token') }
      })
      .then(response => {
      dispatch({
      type: FETCH_MESSAGE,
      payload: response.data.message
      })
      });
      }
      }

      // Private functions
      function _successResponse(dispatch, response){
      // If request is valid...
      // - Update state to indicate user is authenticated
      dispatch({ type: AUTH_USER });
      // - Save the JWT token
      localStorage.setItem('token', response.data.token);
      // - redirect to the route '/feature'
      browserHistory.push('/feature');
      }









      share|improve this question















      I've created a private function called _successResponse to handle successful responses from my promise.



      The challenge was passing the dispatch function to the _successResponse which is being passed to the .then method as a callback.



      I accomplished this by currying using .bind. I would love to get feedback on this approach.



      import axios from 'axios';
      import { browserHistory } from 'react-router';
      import {
      AUTH_USER,
      AUTH_ERROR,
      UNAUTH_USER,
      FETCH_MESSAGE
      } from './types';

      const ROOT_URL = 'http://localhost:3090';

      export function signinUser({ email, password }){
      return function(dispatch){
      // Submit email/password to server
      axios.post(`${ROOT_URL}/signin`, { email, password })
      .then(_successResponse.bind(null, dispatch))
      .catch(() => {dispatch(authError('Bad Login Info'))})
      }
      }

      export function signupUser({email, password}){
      return function(dispatch){
      axios.post(`${ROOT_URL}/signup`, { email, password })
      .then(_successResponse.bind(null, dispatch))
      .catch(response => {dispatch(authError(response.response.data.error))});
      }
      }

      export function authError(error){
      return {
      type: AUTH_ERROR,
      payload: error
      }
      }

      export function signoutUser(){
      localStorage.removeItem('token');

      return { type: UNAUTH_USER }
      }

      export function fetchMessage(){
      return function(dispatch){
      axios.get(ROOT_URL, {
      headers: { authorization: localStorage.getItem('token') }
      })
      .then(response => {
      dispatch({
      type: FETCH_MESSAGE,
      payload: response.data.message
      })
      });
      }
      }

      // Private functions
      function _successResponse(dispatch, response){
      // If request is valid...
      // - Update state to indicate user is authenticated
      dispatch({ type: AUTH_USER });
      // - Save the JWT token
      localStorage.setItem('token', response.data.token);
      // - redirect to the route '/feature'
      browserHistory.push('/feature');
      }






      javascript ajax react.js promise redux






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Nov 14 at 23:48









      Sᴀᴍ Onᴇᴌᴀ

      7,67561748




      7,67561748










      asked Nov 30 '17 at 15:13









      user2731105

      61




      61






















          1 Answer
          1






          active

          oldest

          votes

















          up vote
          1
          down vote













          Currying?



          1



          Photo hosted via unsplash, taken by Monika Grabkowska



          Yes you used Function.bind() to fix the callback function as the first argument to the private function, and this is a good approach to avoid excess functions and reduce the number of lines. While the concept is similar, what this code uses is actually Partial Application. Read more about the differences in this article.





          The first couple functions appear to catch errors, but fetchMessage() doesn't appear to. Maybe you have updated it since you posted it but if not, I would suggest adding error handling there too.





          You could consider using async and await to reduce the .then() callbacks.






          share|improve this answer





















            Your Answer





            StackExchange.ifUsing("editor", function () {
            return StackExchange.using("mathjaxEditing", function () {
            StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix) {
            StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
            });
            });
            }, "mathjax-editing");

            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: "196"
            };
            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',
            convertImagesToLinks: false,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: null,
            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%2fcodereview.stackexchange.com%2fquestions%2f181681%2fdrying-out-my-action-creators%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown

























            1 Answer
            1






            active

            oldest

            votes








            1 Answer
            1






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes








            up vote
            1
            down vote













            Currying?



            1



            Photo hosted via unsplash, taken by Monika Grabkowska



            Yes you used Function.bind() to fix the callback function as the first argument to the private function, and this is a good approach to avoid excess functions and reduce the number of lines. While the concept is similar, what this code uses is actually Partial Application. Read more about the differences in this article.





            The first couple functions appear to catch errors, but fetchMessage() doesn't appear to. Maybe you have updated it since you posted it but if not, I would suggest adding error handling there too.





            You could consider using async and await to reduce the .then() callbacks.






            share|improve this answer

























              up vote
              1
              down vote













              Currying?



              1



              Photo hosted via unsplash, taken by Monika Grabkowska



              Yes you used Function.bind() to fix the callback function as the first argument to the private function, and this is a good approach to avoid excess functions and reduce the number of lines. While the concept is similar, what this code uses is actually Partial Application. Read more about the differences in this article.





              The first couple functions appear to catch errors, but fetchMessage() doesn't appear to. Maybe you have updated it since you posted it but if not, I would suggest adding error handling there too.





              You could consider using async and await to reduce the .then() callbacks.






              share|improve this answer























                up vote
                1
                down vote










                up vote
                1
                down vote









                Currying?



                1



                Photo hosted via unsplash, taken by Monika Grabkowska



                Yes you used Function.bind() to fix the callback function as the first argument to the private function, and this is a good approach to avoid excess functions and reduce the number of lines. While the concept is similar, what this code uses is actually Partial Application. Read more about the differences in this article.





                The first couple functions appear to catch errors, but fetchMessage() doesn't appear to. Maybe you have updated it since you posted it but if not, I would suggest adding error handling there too.





                You could consider using async and await to reduce the .then() callbacks.






                share|improve this answer












                Currying?



                1



                Photo hosted via unsplash, taken by Monika Grabkowska



                Yes you used Function.bind() to fix the callback function as the first argument to the private function, and this is a good approach to avoid excess functions and reduce the number of lines. While the concept is similar, what this code uses is actually Partial Application. Read more about the differences in this article.





                The first couple functions appear to catch errors, but fetchMessage() doesn't appear to. Maybe you have updated it since you posted it but if not, I would suggest adding error handling there too.





                You could consider using async and await to reduce the .then() callbacks.







                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered Nov 14 at 23:48









                Sᴀᴍ Onᴇᴌᴀ

                7,67561748




                7,67561748






























                     

                    draft saved


                    draft discarded



















































                     


                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function () {
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f181681%2fdrying-out-my-action-creators%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

                    List directoties down one level, excluding some named directories and files

                    list processes belonging to a network namespace

                    list systemd RuntimeDirectory mounts