[英]How can I handle a vuex dispatch response?
I'm raising the white flag and asking for suggestions even though I feel the answer is probably right in front of my face.即使我觉得答案可能就在我面前,我还是举起了白旗并寻求建议。
I have a login form that I am submitting to an api (AWS) and acting on the result.我有一个登录表单,我要提交给 api (AWS) 并根据结果采取行动。 The issue I am having is once the handleSubmit
method is called, I am immediately getting into the console.log
statement... which to no surprise returns dispatch result: undefined
我遇到的问题是一旦调用了handleSubmit
方法,我就会立即进入console.log
语句......毫不奇怪返回dispatch result: undefined
I realize this is likely not a direct function of vue.js, but how I have the javascript set executing.我意识到这可能不是 vue.js 的直接功能,而是我如何执行 javascript 集。
Here is my login component:这是我的登录组件:
// SignInForm.vue
handleSubmit() {
try {
const {username, password} = this.form;
this.$store.dispatch('user/authenticate', this.form).then(res => {
console.log('dispatch result: ', res);
});
} catch (error) {
console.log("Error: SignInForm.handleSubmit", error);
}
},
...
Here is what my store is doing.这是我的商店正在做的事情。 I'm sending it to a UserService
I've created.我将它发送到我创建的UserService
。 Everything is working great.一切都很好。 I am getting the correct response(s) and can log everything out I need.我得到了正确的响应,并且可以记录我需要的所有内容。 The UserService
is making an axios request (AWS Amplify) and returning the response. UserService
发出 axios 请求 (AWS Amplify) 并返回响应。
// user.js (vuex store)
authenticate({state, commit, dispatch}, credentials) {
dispatch('toggleLoadingStatus', true);
UserService.authenticate(credentials)
.then(response => {
dispatch('toggleLoadingStatus', false);
if (response.code) {
dispatch("setAuthErrors", response.message);
dispatch('toggleAuthenticated', false);
dispatch('setUser', undefined);
// send error message back to login component
} else {
dispatch('toggleAuthenticated', true);
dispatch('setUser', response);
AmplifyEventBus.$emit("authState", "authenticated");
// Need to move this back to the component somehow
// this.$router.push({
// name: 'dashboard',
// });
}
return response;
});
},
...
Where I'm getting stuck at is, if I have error(s) I can set the errors in the state, but I'm not sure how to access them in the other component.我遇到的问题是,如果我有错误,我可以在状态中设置错误,但我不确定如何在其他组件中访问它们。 I've tried setting the data
property to a computed method that looks at the store, but I get errors.我尝试将data
属性设置为查看商店的计算方法,但出现错误。
I'm also struggling to use vue-router if I'm successfully authenticated.如果我成功通过身份验证,我也很难使用 vue-router。 From what I've read I really don't want to be doing that in the state anyway -- so that means I need to return the success response back to the SignInForm
component so I can use vue-router to redirect the user to the dashboard.从我读过的内容来看,我真的不想在状态下这样做——所以这意味着我需要将成功响应返回给SignInForm
组件,以便我可以使用 vue-router 将用户重定向到仪表盘。
Yep.是的。 Just took me ~6 hours, posting to SO and then re-evaluating everything (again) to figure it out.只花了我大约 6 个小时,发布到 SO,然后(再次)重新评估所有内容以解决问题。 It was in fact, somewhat of a silly mistake.事实上,这是一个有点愚蠢的错误。 But to help anyone else here's what I was doing wrong...但是为了帮助其他人,我做错了……
// SignInForm.vue
async handleSubmit() {
try {
await this.$store.dispatch("user/authenticate", this.form)
.then(response => {
console.log('SignInForm.handleSubmit response: ', response); // works
if (response.code) {
this.errors.auth.username = this.$store.getters['user/errors'];
} else {
this.$router.push({
name: 'dashboard',
});
}
}).catch(error => {
console.log('big problems: ', error);
});
} catch (error) {
console.log("Error: SignInForm.handleSubmit", error);
}
},
...
Here's my first mistake: I was calling from an async
method to another method - but not telling that method to be async
so the call(er) method response was executing right away.这是我的第一个错误:我从一个async
方法调用另一个方法 - 但没有告诉该方法是async
所以 call(er) 方法响应立即执行。 Here's the updated vuex store:这是更新后的 vuex 商店:
// user.js (vuex store)
async authenticate({state, commit, dispatch}, credentials) { // now async
dispatch('toggleLoadingStatus', true);
return await UserService.authenticate(credentials)
.then(response => {
console.log('UserService.authenticate response: ', response); // CognitoUser or code
dispatch('toggleLoadingStatus', false);
if (response.code) {
dispatch("setAuthErrors", response.message);
dispatch('toggleAuthenticated', false);
dispatch('setUser', undefined);
} else {
dispatch('toggleAuthenticated', true);
dispatch('setUser', response);
AmplifyEventBus.$emit("authState", "authenticated");
}
return response;
});
},
...
My second error was that I wasn't returning the result of the method at all from the vuex store.我的第二个错误是我根本没有从 vuex 商店返回该方法的结果。
Old way:旧方式:
UserService.authenticate(credentials)
Better way:更好的方法:
return await UserService.authenticate(credentials)
Hope this saves someone a few hours.希望这可以为某人节省几个小时。 ¯_(ツ)_/¯ ¯_(ツ)_/¯
This works for Vue3:这适用于 Vue3:
export default {
name: 'Login',
methods: {
loginUser: function () {
authenticationStore.dispatch("loginUser", {
email: 'peter@example.com',
})
.then(response => {
if (response.status === 200) {
console.log('Do something')
}
});
},
},
}
In the store you can simply pass back the http response which is a promise.在商店中,您可以简单地传回 http 响应,这是一个承诺。
const authenticationStore = createStore({
actions: {
loginUser({commit}, {email}) {
const data = {
email: email
};
return axios.post(`/authentication/login/`, data)
.then(response => {
toastr.success('Success')
return response
})
},
}
})
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.