I need to load some data before my route should be visible:
beforeRouteEnter(to, from, next) {
this.$store.dispatch('loadLeaderboard');
}
but obviously I don't have access to this, so I have to change it to
beforeRouteEnter(to, from, next) {
next(vm => {
vm.$store.dispatch('loadLeaderboard');
});
}
but that loads the page before my action completes. vm.$store.dispatch returns a promise.
Is there a way to get access to my VM, and call next once my vm.$store.dispatch resolves?
Something like this, which obviously wouldn't work.
beforeRouteEnter(to, from, next) {
vm.$store.dispatch('loadLeaderboard').then(next);
}
or this, would I would hope worked
beforeRouteEnter(to, from, next) {
next(vm => vm.$store.dispatch('loadLeaderboard'));
},
Thanks.
This is a complex problem. You can import the store and do a store.dispatch. It works, but can generate many problems depending its architecture, for example, it generate problems with circular dependency.
If its component is a root, the problem is bigger, because the vue-router hooks dont work on root component. For example, if ou need to load some data before initialize the application, you dont have many solutions. Maybe you can load the data and lazily initialize the router, but.. no.
So, in you case, import the store maybe resolve.
Thanks for the reply, importing the store works but feels messy. Isn't there any way for the next function to see if the callback returns a promise, and wait for that to resolve if so?
To use this, there should be an instance of component. If there is an instance, then the component is already created. 😑
And using store is not messy, its totally okay 👍 .
@SteveEdson Could you please share the solution that you went with finally. I am facing the similar problem and can't decide.
Just import the service (e.g. foo) and use it directly instead of relying on this.$foo:
import foo from '../services/foo'
Then use in your beforeRouteEnter definition:
async beforeRouteEnter(to, from, next) {
await foo.loadSomething();
next();
},
Good afternoon you can also access to the data insite the next() function.
This is my example
beforeRouteEnter(to, from, next) {
next(vm => {
if(from.path === '/somePath' && vm.someData.length > 0) {
vm.$router.push({ name: 'some_name'})
} else {
vm.$router.push({ name: 'another_name'})
}
})
},
or justnext('some_name')
Why we didn't use beforeMount()
In this case I used beforeMount() instead of beforeRouteEnter() and it's working
Thanks
as per @stefanosandes
javascript
import store from '@/store'
As long as you'r exporting your vuex.store instance you would then use 'store' rather then 'this.$store'.
I think 'store' must be singleton.
You can access the store, providing this is _not the initial route_, via the from parameter, if you want to avoid using a singleton:
beforeRouteEnter(to, from, next) {
const store = from.matched[0].instances.default.$store
await store.dispatch('load')
next()
}
@diachedelic This assumes that you are coming from a previous route and will not work if you intend to do this on your initial page load.
Most helpful comment
@SteveEdson Could you please share the solution that you went with finally. I am facing the similar problem and can't decide.