vuexorm in ssr hydration issue
-
Data isn’t hydrating properly when I use:
items:
<template> <q-page padding class="flex"> <div class="q-pa-md"> <div class="q-col-gutter-md row items-start"> <q-card flat class="col-12"> <h3 class="text-primary">Shop</h3> <h2 class="text-primary">BE FASHION</h2> </q-card> <ItemContent v-for="item in items" :key="item.id" :item="item" /> </div> </div> </q-page> </template> <script type="text/javascript"> import Item from "../store/models/Item"; export default { name: "Shop", components: { ItemContent: () => import("components/ItemConent") }, computed: { items: () => Item.all() }, preFetch() { return Item.$fetch().then(response => { console.log("success", response); }); } }; </script>
component - itemcontent:
<template> <q-page class="flex flex-center"> <q-card flat class="main-card flex"> <q-card-section> <router-link :to="{ name: ROUTE_NAME_ITEM, params: { id: item.id } }"> <q-card dark shadow-transition bordered class="bg-secondary hover-shadow my-card" > <q-card-section> <q-img :src="item.image" class="item-image" style="width: 250px; height: 280px;" alt="11XI products" /> <div class="text-h6">{{ item.title }}</div> <div class="text-subtitle2">By: {{ item.designer }}</div> </q-card-section> <q-separator dark inset /> <q-card-section> {{ item.price }} </q-card-section> </q-card> </router-link> </q-card-section> </q-card> </q-page> </template> <script> import { ROUTE_NAME_ITEM } from "../constants"; export default { name: "ItemContent", props: { item: { type: Object, required: true } }, data: () => ({ hovered: false, ROUTE_NAME_ITEM }) }; </script>
vuexorm index.js:
import Vue from "vue"; import Vuex from "vuex"; import VuexORM from "@vuex-orm/core"; import Item from "../store/models/Item"; import VuexORMAxios from "@vuex-orm/plugin-axios"; import http from "../store/http"; import createPersistedState from "vuex-persistedstate"; import User from "../store/models/User"; Vue.use(Vuex); const database = new VuexORM.Database(); database.register(Item, item); database.register(User); VuexORM.use(VuexORMAxios, { database, http }); const VuexORMPlugin = VuexORM.install(database); export default function({ ssrContext }) { const plugins = []; plugins.push(VuexORMPlugin); if (!ssrContext) { plugins.push( createPersistedState({ filter: ({ payload }) => (payload ? payload.entity !== "users" : true) }) ); } const Store = new Vuex.Store({ modules: { }, plugins, // enable strict mode (adds overhead!) // for dev mode only strict: process.env.DEV }); return Store; }
item model:
import { Model } from "@vuex-orm/core"; export default class Item extends Model { static get entity() { return "api/items"; } static fields() { return { id: this.string(""), title: this.string(""), summary: this.string(""), status: this.string(""), designer: this.string(""), description: this.string(""), image: this.string(""), price: this.number(0), cart: this.number(0) }; } static methodConf = { methods: { $update: { http: { method: "patch" } } } }; }
It doesn’t load anything on the page and or it doesn’t throw any errors either. There’s no errors and or give a response in console. The only thing that happens is when I load the page for the first time it shows half the page moved to the left and or loads slow.
-
@bellagrunt said in vuexorm in ssr hydration issue:
computed: {
items: () => Item.all()
},Interesting. I don’t know how SSR mode works in the context of vueorm. BTW this fragment is one of the first I would check - I would put some console.log or debugger in this:
computed: { items: () => Item.all() },
something like this:
computed: { items () { let ret = Item.all() // debugger OR console.log(ret) return ret } },
-
Thanks for getting back to me. Same thing happened with console.log.
-
The interesting part is that when I don’t try to use preFetch and load the data on the page with the hydration error —
created() { Item.$fetch() .then(response => { console.log("success", response); }) .catch(response => { console.log("error", response.status, response.errors); this.errors = response.errors; }); }
In terminal it gets a “undefined” but when I do something like:
preFetch() { return Item.$fetch().then(response => { console.log("success", response); }); },
It doesn’t load anything on the page but I don’t get any errors or undefined
-
@bellagrunt Hmm, I didn’t work with SSR, so can’t say about prefetch. Anyhow, from Vue’s pov, if you’re using “created()” then imho it’s quite early in component lifecycle:
https://vuejs.org/v2/guide/instance.html#Lifecycle-Diagram
In typical situation, I would use a “mounted()”.
Does your solution works without SSR in “normal” SPA mode?
-
yea, it works fine without ssr (spa) but i need ssr for this project tried mounted before and still gave me the hydration error. i asked the vuexorm team as well. came up with:
preFetch() { return this.$axios .get("http://localhost:8000/api/items") .then(response => { Item.insert({ data: response.data }); console.log("success", response); }) .catch(response => { console.log(response.error); this.error = response.error; }); }
Data would show maybe 30% of the time with no undefined. Not sure if I mentioned but I’m using the vuexorm-axios plugin. I was thinking of calling in axios separately from vuexorm and not use the axios plugin.
-
I think I got it to work, actually. But I was wondering, how do you validate if preFetched worked? I set up the same exact project in vuex and modified my vuexorm project. got the same results of the website rendering to the left when loading the first time.
-
The only slight difference is that it on terminal i dont get an “undefined” anymore and it loads a little quicker.