Gunaraj Khatri
Gunaraj Khatri

Reputation: 183

ASync/Await is not working as expected in router.BeforeEach guard in vue?

this is my router guard :

router.beforeEach(async (to,from,next)=>{   
  await store.dispatch('GetPermission'); 
  if(to.matched.some(record => record.meta.requireAuth)){
    let permissions=store.state.permissions; //getting empty 
    console.log(permissions);
    if(permissions.filter(per => (per.name === 'read_list').length!=0)){
      next({
        path:'/dashboard/create'
      }) 
    }
    else{
        next()  
    }
  
  }
  // else if(to.matched.some(record => record.meta.requireAuth)){
  //     if(store.token!=null){
  //     next({
  //       path:'/dashboard'
  //     }) 
  //   }
  //   else{
  //     next()
  //   }
  // }
  else{
    next()
  }

});

problem is here though i m using await in dispatch method , i m not getting state value of permissions which is initially empty here is vuex store code :

GetPermission(context){
            axios.defaults.headers.common['Authorization']='Bearer ' + context.state.token
            axios.get('http://127.0.0.1:8000/api/user').then((response)=>{
                console.log(response)
                context.commit('Permissions',response.data.permission)
            })
//mutation:
Permissions(state,payload){
            state.permissions=payload
        }
//state
state:{
        error:'',
        token:localStorage.getItem('token') || null,
        permissions:'',
        success:'',
        isLoggedin:'',
        LoggedUser:{}
    }

help me to solve it please ??

Upvotes: 2

Views: 4785

Answers (1)

Rasik
Rasik

Reputation: 45

actions in Vuex are asynchronous. The only way to let the calling function (initiator of action) to know that an action is complete - is by returning a Promise and resolving it later.

Here is an example: myAction returns a Promise, makes a http call and resolves or rejects the Promise later - all asynchronously

actions: {
myAction(context, data) {
    return new Promise((resolve, reject) => {
        // Do something here... lets say, a http call using vue-resource
        this.$http("/api/something").then(response => {
            // http success, call the mutator and change something in state
            resolve(response);  // Let the calling function know that http is done. You may send some data back
        }, error => {
            // http failed, let the calling function know that action did not work out
            reject(error);
        })
    })
}

}

Now, when your Vue component initiates myAction, it will get this Promise object and can know whether it succeeded or not. Here is some sample code for the Vue component:

export default {
mounted: function() {
    // This component just got created. Lets fetch some data here using an action
    this.$store.dispatch("myAction").then(response => {
        console.log("Got some data, now lets show something in this component")
    }, error => {
        console.error("Got nothing from server. Prompt user to check internet connection and try again")
    })
}

}

Also,you are calling same route when no permission match, in that case it always call your same route and make infinite loop. Redirect to access denied page if permission denied.

Upvotes: 1

Related Questions