Search code examples
javascriptvue.jsvuejs2vue-routervue-resource

VueRouter wait for ajax is done


I am building SPA and the problem is checking if user is admin or not.

After Vue.auth.getUserInfo() I want to stop whole application and wait for API response, Vue.auth.user.isAdmin is always false because I don't have response from api...

Here is router.beforeEach

router.beforeEach((to, from, next) => {

   if(Vue.auth.user.authenticated == false) {
       Vue.auth.getUserInfo();
   }

   if(Vue.auth.user.isAdmin) {
      next({ name: 'admin.index' })
   } else {
      next({name: 'client.index'})
   }
}

Get user info method:

getUserInfo() {
    Vue.http.get('/api/me')
        .then(({data}) => {
            this.user = data;
        }, () => {
            this.logout();
        })
}

Solution

  • Assuming the state of Vue.auth.user.isAdmin is managed within your Vue.auth.getUserInfo() logic, you can try a promise approach (untested):

    getUserInfo() {
      return new Promise((resolve, reject) => {
        Vue.http.get('/api/me')
          .then(({data}) => {
            this.user = data;
            // Or, to use when consuming this within the then() method:
            resolve(data);
          }, () => {
            reject();
          })
      })
    }
    

    Then, when you consume it in your guard (https://router.vuejs.org/en/advanced/navigation-guards.html):

    // A couple small auth/guard helper functions
    function guardCheck(next) {
      if(Vue.auth.user.isAdmin) {
        next({ name: 'admin.index' })
      } else {
        next({name: 'client.index'})
      }
    }
    function guardLogout(next) {
      Vue.auth.user.logout()
        .then(() => {
          next({ name: 'home.index', params: { logout: success }})
        })
    }
    
    router.beforeEach((to, from, next) => {
      if(Vue.auth.user.authenticated === false && !to.matched.some(record => record.meta.isGuest)) {
        Vue.auth.getUserInfo()
          .then((user) => {
            guardCheck(next)
          })
          .catch(() => {
            // Not sure how your logout logic works but maybe...
            guardLogout(next)
          })
      } else {
         guardCheck(next)
      }
    }