vuex-cache
vuex-cache copied to clipboard
'Dispatch' undefined when inside new Nuxt fetch()
In Nuxt 2.12+, there's a new fetch() method.
Example:
<script>
export default {
async fetch() {
await this.$store.cache.dispatch('getUser');
},
};
</script>
Results in:
ERROR Error in fetch(): Cannot read property 'dispatch' of undefined
at VueComponent.fetch (server.js:6668:29)
at VueComponent.serverPrefetch (server.js:2515:31)
at waitForServerPrefetch (node_modules/vue-server-renderer/build.dev.js:8276:34)
at renderComponentInner (node_modules/vue-server-renderer/build.dev.js:8426:3)
at renderComponent (node_modules/vue-server-renderer/build.dev.js:8383:5)
at RenderContext.renderNode (node_modules/vue-server-renderer/build.dev.js:8294:5)
at RenderContext.next (node_modules/vue-server-renderer/build.dev.js:2598:23)
at cachedWrite (node_modules/vue-server-renderer/build.dev.js:2451:9)
at renderElement (node_modules/vue-server-renderer/build.dev.js:8544:5)
at renderNode (node_modules/vue-server-renderer/build.dev.js:8296:5)
My vuex-cache.js in ~/plugins:
import createVuexCache from 'vuex-cache';
export default ({ store, isHMR }) => {
if (process.browser) {
if (isHMR) {
return;
}
const options = {
timeout: 2 * 60 * 60 * 1000, // Equal to 2 hours in milliseconds.
};
const setupVuexCache = createVuexCache(options);
window.onNuxtReady(() => setupVuexCache(store));
}
};
I assume it's just because it is attempting to dispatch server-side but vuex-cache hasn't attached itself yet correctly to the $store instance.
Not sure if there's a solution to ensure that all dispatches server-side bypass the cache, and all client-side navigations include the cache action - barring doing twice the dispatch calls wrapped within if (process.browser) { checks?
I assume it's just because it is attempting to dispatch server-side but vuex-cache hasn't attached itself yet correctly to the $store instance.
This happens if you declare the plugin like in README.md. That configuration only allow vuex-cache to work client-side.
module.exports = {
...,
plugins: [
...,
{ src: '~/plugins/vuex-cache.js', ssr: false },
]
};
Not sure if there's a solution to ensure that all dispatches server-side bypass the cache, and all client-side navigations include the cache action - barring doing twice the dispatch calls wrapped within if (process.browser) { checks?
process.browser is probably the best choice. Since vuex-cache uses a simple Map as store for your actions and I don't think there's a way to use it on both client and server.
if (process.browser)
await this.$store.cache.dispatch('getUser');
else
await this.$store.dispatch('getUser');
process.browseris probably the best choice. Since vuex-cache uses a simpleMapas store for your actions and I don't think there's a way to use it on both client and server.if (process.browser) await this.$store.cache.dispatch('getUser'); else await this.$store.dispatch('getUser');
Perhaps then there would be an opportunity to add a hook inside vuex-cache to check for typeof window === "undefined" and bypass itself allowing the dispatch to pass through directly - rather than force the user to define the check for every dispatch?
Perhaps then there would be an opportunity to add a hook inside vuex-cache to check for typeof window === "undefined" and bypass itself allowing the dispatch to pass through directly - rather than force the user to define the check for every dispatch?
I don't think so, vuex-cache can be executed without window because just depends on Vuex, Promise and Map. You can change declaration of the plugin in nuxt.config to allow vuex-cache in SSR too. It may fix the problem.
module.exports = {
...,
plugins: [
...,
'~/plugins/vuex-cache.js', // instead of { src: '~/plugins/vuex-cache.js', ssr: false }
]
};
It's not fixing problem, it turns out just an empty store