Search code examples
javascriptvue.jspromisecallbackvuex

JavaScript can we carry what should be inside then() into method with parameters and call it


How can I avoid repeating code in then() when I handle callback It is vuex module for user login and registration

    login({ commit }, user) {
        return AuthService.login(user).then(
            user => {
                commit('loginSuccess', user);
                return Promise.resolve(user);
            },
            error => {
                commit('loginFailure');
                return Promise.reject(error);
            }
        );
    },
    register({ commit }, user) {
        return AuthService.register(user).then(
            response => {
                commit('registerSuccess');
                return Promise.resolve(response.data);
            },
            error => {
                commit('registerFailure');
                return Promise.reject(error);
            }
        );
    }

I would like to make a function with parameters someting like this it gets mutation names and handles promse

function handleCallback(strMutationName1,strMutationName2, response, error) {
    response => {
       commit(strMutationName1, response.data)
       return Promise.resolve(response.data);
    },
    error => {
       commit(strMutationName2);
       return Promise.reject(error)
    }
}
And call previous methods like this 
    login({ commit }, user) {
        return AuthService.login(user).then(
            handleCallback('loginSuccess','loginFailure', response, error)
        );
    },
    register({ commit }, user) {
        return AuthService.register(user).then(
            handleCallback('registerSuccess','registerFailure', response, error)
        );
    }

Solution

  • No, then has two parameters so you would need to create two functions:

    function successCallback(commit, name) {
        return response => {
            commit(name, response)
            return Promise.resolve(response);
        };
    }
    function failureCallback(commit, name) {
        return error => {
            commit(name)
            return Promise.reject(error);
        };
    }
    

    Then call them like

    login({ commit }, user) {
        return AuthService.login(user).then(successCallback(commit, 'loginSuccess'), failureCallback(commit, 'loginFailure'));
    },
    register({ commit }, user) {
        return AuthService.register(user).then(successCallback(commit, 'registerSuccess'), failureCallback(commit, 'registerFailure'));
    }
    

    To make a single helper, you should either wrap the whole then callback

    function handle(commit, name, promise) {
        return promise.then(successCallback(commit, name+'Success'), failureCallback(commit, name+'Failure');
    }
    

    login({ commit }, user) {
        return handle(commit, 'login', AuthService.login(user));
    },
    register({ commit }, user) {
        return handle(commit, 'register', AuthService.register(user));
    }
    

    or use spread syntax in the call, and return a tuple from the helper:

    function handleCallbacks(commit, name) {
        return [successCallback(commit, name+'Success'), failureCallback(commit, name+'Failure')];
    }
    

    login({ commit }, user) {
        return AuthService.login(user).then(...handleCallbacks(commit, 'login'));
    },
    register({ commit }, user) {
        return AuthService.register(user).then(...handleCallbacks(commit, 'register'));
    }