Giedrius
Giedrius

Reputation: 1390

Vue Router + Vuex: how to make beforeEach route guard wait for Vuex state change?

In my SPA, part of the initialization when the page loads is fetching the logged in user from the API, and then the user record is stored in the state alongside with initialized flag.

In the router beforeEach guard I need to check whether the user is logged in, but for it to function correctly, I need to wait until the initialized flag is set to true. How can I make my function wait for that? Should I hook into the store and create a watcher, or set up another variable as a promise or something?

Thanks!

Upvotes: 1

Views: 2188

Answers (1)

Decade Moon
Decade Moon

Reputation: 34306

You can implement a rudimentary "pause" feature on the router like this (code is untested):

// Router is initially not paused
let pausedResolve = null
let pausedPromise = Promise.resolve()

router.beforeEach(async (to, from, next) => {
  await pausedPromise
  next()
})

function pause() {
  if (!pausedResolve) {
    pausedPromise = new Promise(resolve => pausedResolve = resolve)
  }
}

function resume() {
  if (pausedResolve) {
    pausedResolve()
    pausedResolve = null
  }
}

After creating the router, immediately call pause(), then after logging in call resume() (you can do this in your Vuex code maybe).

The benefit of this implementation is that the router code is not dependent on the Vuex code (it's generally a good idea to keep code loosely-coupled whenever possible).

Upvotes: 1

Related Questions