Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Async data mixin with content area handling (is it really needed on client side? because mixin as applied to all components)
import blockRouter from '@/router/block-router'
// TODO ssr move to lib and reuse with entry-server.js
function loadBlocksAsyncData({ store, route, model }) {
const contentAreas = Object.keys(model)
.filter(key => key.endsWith('ContentArea'))
.map(key => model[key])
const blockPromises = contentAreas
.map(blocks => blockRouter.resolveComponents(blocks))
.reduce((acc, val) => acc.concat(val), [])
.filter(resolved => resolved.component.asyncData)
.map(resolved => resolved.component.asyncData({
store,
route,
options: resolved.component,
// ssrContext: context,
model
}))
return Promise.all(blockPromises)
}
export default {
beforeMount() {
const { asyncData, propsData } = this.$options
if (asyncData) {
// assign the fetch operation to a promise
// so that in components we can do `this.dataPromise.then(...)` to
// perform other tasks after data is ready
this.dataPromise = asyncData({
store: this.$store,
route: this.$route,
options: this.$options,
model: propsData ? propsData.model : undefined
}).then(data => loadBlocksAsyncData({
store: this.$store,
route: this.$route,
model: data
}))
// TODO ssr catch errors
}
},
beforeRouteUpdate(to, from, next) {
const { asyncData, propsData } = this.$options
if (asyncData) {
this.loading = true
asyncData({
store: this.$store,
route: to,
options: this.$options,
model: propsData ? propsData.model : undefined
}).then(data => loadBlocksAsyncData({
store: this.$store,
route: to,
model: data
})).then(next).catch(next)
} else {
next()
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment