Best practice to change the route (VueRouter) after a mutation (Vuex)

Hello,

I’ve searched a lot, but there is no clear answer to that. Basically, what should be the best practice to automatically change a route after a mutation?

Ex: I click a button to login() -> action login that makes an http call -> mutation LOGIN_SUCCESSFUL -> I want to redirect the user to the main page $router.go()

  • Should I wrap the action in a Promise, and then listen to the result to call the route change from the component?

  • Should I do it directly from the $store?

  • Does vuex-router-sync helps in any way?

Thanks a lot!

1 Like

Actions always return a promise in vuex 2.*. Probably the best solution.

The store is about state, not UI/routing. I would say it’s best to keep that out of the store, but others may disagree.

I guess the important part is to be consistent in all of your app.

No. It only syncs the route object into the store, but doesn’t allow the store to access the router specifically.

3 Likes

Thanks a lot @LinusBorg

Sure, the thing is that if I want to make an http call inside the action, I will need to wrap it in another. Then the question is: is it safe to assume that when the promise is resolved, the mutation has been committed & ended?

I would say that yes, it’s a safe guess. Anyway it looks definitely the best option.

Thanks a lot again,

1 Like

Most Librarys like axios return a promise anyway, so I don’t see a problem here.

is it safe to assume that when the promise is resolved, the mutation has been committed & ended?

Yes, because mutations are synchronous.

Sure, sure. Picture this case, when I want to map the response, or do something with it

login ({ commit }) {

  // http call
  axios.get(...).then( res => {
    let data = res.data;
    commit('DATA_RETRIEVED', data)
 )
}

in this case, we should wrap it in a promise like

login ({ commit }) {

  return new Promise(function(resolve, reject) {
    // http call
    axios.get(...).then( res => {
      commit('DATA_RETRIEVED',  res.data);
      // resolving the promise
      resolve();
    )
  });
}

We could use also async/await. Is that ok or am I overcomplicating this?

1 Like

Not necessary. Since axios.get() already returns a Promise, we can just return this one.

login ({ commit }) {

  // simply add `return`, that's all.
  return axios.get(...).then( res => {
    let data = res.data;
    commit('DATA_RETRIEVED', data)
  })
}
3 Likes

Hey @LinusBorg I am stuck after the ‘DATA_RETRIEVED’ mutation. Where and how can I tell the router to change the route when ‘DATA_RETRIEVED’ is committed. If I do that in component inside of method like this:

submitLoginDetails() {
          //obj for post request
          let userDetails: object = {
            username: this.usernameInputValue,
            password: this.userPasswordValue,
            app: "oneview"
          }

          // dispatch action to make the post request
          this.$store.dispatch('submitLoginDetails', userDetails)

          // if there is no error go to home page
          if(!this.$store.getters.error){
              this.$router.push('/home')
          }
      }

but this does not work, because error property is true even when there is error, because the router.push gets executed before the action and mutation.

dispatch returns a Promise. you should wait for it to resolve.

this.$store.dispatch('submitLoginDetails', userDetails).then(() => {
  // if there is no error go to home page
  if(!this.$store.getters.error){
    this.$router.push('/home')
  }
})
2 Likes

Your action should return a promise, then you can wait for the action to resolve before you change the route.

No matter which HTTP library you use, it should have basic methods that return a promise by default.

return this.$store.dispatch('submit', details).then(() => {
  this.router.push('/home');
});
1 Like

Hi, I’m doing kind of the same, but since I am working with firebase, I just dispatch an action from within the component, firebase also returns a promise from his sign in method in the auth system and once is resolve I commit a login mutation and then I change some states the push a route to the home page, but reading this post you say:

I assume that even though you could push a route from within the store is not a good practice?