vue-router: Data is not set with beforeRouteEnter () before created () method is called
Vue.js / vue-router versions
2.1.10 / 2.2.0
Steps to reproduce
- Fetch some data via the
beforeRouteEnter ()method
data () {
return {
post: null
}
},
beforeRouteEnter (to, from, next) {
getPost(to.params.id, (err, post) => {
if (err) {
// display some global error message
next(false)
} else {
next(vm => {
console.log('next function')
vm.post = post
})
}
})
},
- Log the
created ()andmounted ()method
created () {
console.log('created:', this.post);
},
mounted () {
console.log('mounted:', this.post);
},
What is Expected?
The data fetched during the beforeRouteEnter () method should be set before the created () and mounted () methods occur.
What is actually happening?
The data is null in the created () and mounted () methods.
The ‘created’ and ‘mounted’ console input will occur before the ‘next function’.
About this issue
- Original URL
- State: closed
- Created 7 years ago
- Reactions: 33
- Comments: 24 (4 by maintainers)
This is actually expected, the callback is triggered after a
nextTickthat’s why you don’t have access topostin both hooks.Edit: this is something we might not be able to change on v3 as it is a breaking change but it’s something we plan on improving for v4
I found a workaround that works for me:
BaseLazyLoadingComponent):beforeRouteEnter/Updatelazy loading:It makes sense to me on why this isn’t triggered before created, but why does it have to trigger after mounted as well ?
It’s not an issue, the created hook gets called as soon as the component can be used, and the callback passed to
nextis called after that (a tick after I believe) and has to because setting the local variable wouldn’t have an effect if it was called before. This cannot change.If you want to run some tasks that depend on the data fetched you should put that logic in a method and invoke the method from the callback passed to
next:you can also use a watcher to invoke that method if you have a beforeRouteUpdate hook:
I hope this gives some guidance and clears things 🙂
I just came across this as well:
I solved it with a bit of a cheat – the component CANNOT be used in two separate places – using the following solution (which I chose not to continue with) but it demonstrates that setting data before mounting makes life so much easier:
Vue / Vue Router really does need an elegant solution to this.
I saw this post, which is a cool solution:
But for now, what about passing any data directly into the
createdmethod ?Or:
Though digging around Vue’s source, I see that Vue’s hooks don’t support passing payloads.
So maybe set an option on the instance the
createdhooks run:There really should be a low-effort way to capitalise on the async nature of
beforeRouteEnterso fetched data is simply available during and aftercreatedand we can avoid the additional acrobatics 😦I am confused about why this behaviour would be desirable.
In my scenario, parts of my component that are determined by the fetched data (e.g. a slug for a route and props for child components).
This means that errors occur as the data is null when the component is rendered
I’m also confused! Does https://router.vuejs.org/en/advanced/data-fetching.html#fetching-before-navigation need updating then?
I second that the documentation at fetching-before-navigation then seems incorrect (and led me to this page).
@BenRomberg BRILLIANT!!! Works beautifully!!!
You have access in the callback (first and only argument) of the next function
On Tue, 13 Jun 2017, 17:20 Darren Segal, notifications@github.com wrote: