简体   繁体   English

如何在 Axios 响应 Vuex 上从动作中调用动作?

[英]How to call action from action on Axios response Vuex?

I am trying to implement the following logic: call login then if response is ok, call method for retrieving user data.我正在尝试实现以下逻辑:调用登录然后如果响应正常,则调用用于检索用户数据的方法。

Login action登录操作

loginUser({commit,dispatch}, credentials) {
            const form = new URLSearchParams();
            form.append("login", credentials.login);
            form.append("password", credentials.password);

            const formConfig = {
                headers: {
                    'Content-Type': 'application/x-www-form-urlencoded'
                }
            };

         return  Axios.post(loginUrl, form, formConfig).then(
                (response) => {
                    commit('setErrorMessage', '', {root: true});
                    commit('setAuthenticated', response.headers[authorization]);
                    dispatch('getUserByLoginAuth',credentials.login);
                },
                (error) => {
                    if (error.response.status===500){
                        commit('setErrorMessage', error.response.data.message, {root: true});
                    } else {
                        commit('setErrorMessage', error.response.data, {root: true});
                    }

                });

        },

The second action dispatched from the one above:从上面一个动作发出的第二个动作:

getUserByLoginAuth({commit, getters}, login) {
            return getters.authenticatedAxios.get(userUrl + '/find', {
                params: {
                    login: login
                }
            }).then(
                (response) => {
                    commit('setErrorMessage', '', {root: true});
                    commit('setUser', response.data);
                },
                (error) => {
                    commit('setErrorMessage', error.response.data, {root: true});
                });
        },

This action is called from the second time only(as I understand it is related to promise).此操作仅从第二次开始调用(据我了解它与承诺有关)。

Here is a code from component which dispatches login action这是来自组件的代码,用于调度登录操作

this.$store.dispatch('loginUser', this.credentials).then(() => {
                    this.errorMessage = this.getError;
                    if (this.errorMessage.length) {
                        this.errorOccurred = true;

                    }
                    this.$router.push({path: '/user/' + this.getId});
                });
                this.errorOccurred = false;
            },

Here also I am not sure if I am doing routing in correct place.在这里,我也不确定我是否在正确的位置进行路由。 As I understand then will work with promise from getUser so errorMessage from login might be lost.据我了解,然后将与 getUser 的承诺一起使用,因此登录时的 errorMessage 可能会丢失。 I would like to prevent it and make dispatch of getUser correctly from the first time我想阻止它并从第一次开始正确调度 getUser

I don't entirely follow what you're asking but this seems likely to be a problem:我不完全按照你的要求,但这似乎是一个问题:

dispatch('getUserByLoginAuth',credentials.login);

The problem isn't the call itself.问题不在于通话本身。 The problem is that it's kicking off a new asynchronous action without chaining it onto the existing promises.问题在于它启动了一个新的异步操作,而没有将其链接到现有的 promise 上。 From the perspective of loginUser everything is done, it won't wait for getUserByLoginAuth .loginUser的角度来看,一切都完成了,它不会等待getUserByLoginAuth

The result will be that the then in your component will be called before getUserByLoginAuth is done.结果将是您的组件中的then将在getUserByLoginAuth完成之前被调用。 I would imagine this is why it seems to work the second time, because it's picking up the relevant data from the previous call.我想这就是为什么它似乎第二次工作的原因,因为它从上一次调用中获取相关数据。

The solution would be simply to change it to:解决方案只是将其更改为:

return dispatch('getUserByLoginAuth',credentials.login);

By putting in a return it adds it to the promise chain, so loginUser won't be treated as complete until getUserByLoginAuth is done.通过放入return它会将其添加到承诺链中,因此在getUserByLoginAuth完成之前,不会将loginUser视为完成。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM