docs: not able to get it working
lucasctd opened this issue ยท 13 comments
๐ Is your documentation request related to a problem? Please describe.
I did everything that is in your documentation but it does not seem to work :v
I have a typed attribute in my state which has some methods that I need to use in my component, but when I read the object through the $accessor or the $store itself, it's just a plain object.
I have no idea of what I am doing wrong :/
Here is the interface
export interface Jacket {
getFront(): JacketFront
getBack(): JacketBack
getLeft(): JacketLeftSide
getRight(): JacketRightSide
}
and here is my state (index.ts)
import { GetterTree, ActionTree, MutationTree } from 'vuex'
import { getAccessorType } from 'typed-vuex'
import { Customer } from '~/data/customer'
import { Tab } from '~/data/tab'
import { Jacket, defaultJacket } from '~/data/jacket/jacket'
import { EconomicJacket } from '~/data/jacket/economicJacket'
export const state = () => ({
customer: Customer.genEmptyInstance() as Customer,
currentTab: new Tab('customer', 'Customer') as Tab,
tabs: [
new Tab('customer', 'Customer'),
new Tab('jacket-style', 'Jacket Style'),
] as Tab[],
jackets: [] as Jacket[],
currentJacket: defaultJacket as Jacket
})
export type RootState = ReturnType<typeof state>
export const getters: GetterTree<RootState, RootState> = {
}
export const mutations: MutationTree<RootState> = {
SET_CUSTOMER: (state: RootState, customer: Customer) => {
state.customer = customer
},
SET_CURRENT_TAB: (state: RootState, tab: Tab) => {
state.currentTab = tab
},
SET_JACKETS: (state: RootState, jackets: Jacket[]) => {
state.jackets = jackets
},
SET_CURRENT_JACKET: (state: RootState, jacket: Jacket) => {
state.currentJacket = jacket
},
}
export const actions: ActionTree<RootState, RootState> = {
async loadJackets ({ commit }) {
const jackets: Array<EconomicJacket> = await this.$axios.$get('/json/economic/jackets.json', { responseType: 'json' })
commit('SET_JACKETS', jackets.map(j => EconomicJacket.clone(j)))
}
}
export const accessorType = getAccessorType({
state,
getters,
mutations,
actions,
modules: {
},
})
so in my component I am trying to call a method
this.$accessor.currentJacket.getFront()
but I always get tsthis.$accessor.currentJacket.getFront is not a function
if I call this method inside the store, it will work, the problem is when the data is passed to the component.
never mind, just disabled SSR and it worked xD
@lucasctd You shouldn't need to disable SSR - and in fact this shouldn't affect the typing of the accessor. Would you provide a reproduction?
I may provide you on Thursday, I have to deliver the project tomorrow so I am in a hurry xD
About the SSR thing, I set my nuxt project target to "static". They may not work together I guess since the "static" is a client only project.
I don't know too much about how SSR works though, so pls correct me if I am wrong on something I said above XD
according to the docs
https://nuxtjs.org/docs/2.x/configuration-glossary/configuration-target
the target should be:
'server': For server side rendering
'static': For static sites
so I think yeah, it does not make sense to let SSR true for static websites.
@lucasctd Both server and static targets involve SSR (one is per-request, and the other is at generate time). Unless you have specifically set ssr: false
(which I wouldn't recommend), Nuxt will still server-render your pages with static sites.
When using SSR, Nuxt stringifies your store state into an object and then passes this to the frontend/client within the HTML. So if you are expecting an object in the initial store data (currentJacket
) to have a function as a property, it won't work with server-rendering - which likely explains the issue you're experiencing.
@danielroe it's probably the reason why I was getting
WARN Cannot stringify arbitrary non-POJOs Navigation
in my console.
So what you are saying is that, since I need the typed object I can't use SSR, right?
@lucasctd I would just use a getter for currentJacket
that adds the correct function as a property.
so you mean casting the plain object to a typed one in the Getter?
also, sorry for bother you but I tried to create modules as you did in here, but now I am getting unknown action type: loadJackets
xD
the store:
import { getAccessorType, mutationTree, actionTree } from 'typed-vuex'
import { Tab } from '~/data/tab'
import * as customerModule from '~/store/customer'
import * as jacketModule from '~/store/jacket'
export const state = () => ({
currentTab: new Tab('customer', 'Customer') as Tab,
tabs: [
new Tab('customer', 'Customer'),
new Tab('jacket-style', 'Jacket Style'),
] as Tab[],
})
type RootState = ReturnType<typeof state>
export const getters = {
}
export const mutations = mutationTree(state, {
setCurrentTab(state: RootState, tab: Tab) {
state.currentTab = tab
},
})
export const actions = actionTree(
{ state, getters, mutations },
{
}
)
export const accessorType = getAccessorType({
state,
getters,
mutations,
actions,
modules: {
customerModule,
jacketModule
},
})
the module
import { getterTree, mutationTree, actionTree } from 'typed-vuex'
import { Jacket, defaultJacket } from '~/data/jacket/jacket'
import { EconomicJacket } from '~/data/jacket/economicJacket'
export const state = () => ({
jackets: [] as Jacket[],
currentJacket: defaultJacket as Jacket
})
export const getters = getterTree(state, {
})
export const mutations = mutationTree(state, {
setJackets(state, jackets: Jacket[]) {
state.jackets = jackets
},
setCurrentJacket(state, jacket: Jacket) {
state.currentJacket = jacket
}
})
export const actions = actionTree(
{ state, getters, mutations },
{
async loadJackets ({ commit }) {
const jackets: Array<EconomicJacket> = await this.$axios.$get('/json/economic/jackets.json', { responseType: 'json' })
commit('setJackets', jackets.map(j => EconomicJacket.clone(j)))
}
}
)
and I call it running the following code:
this.$store.dispatch('loadJackets')
and to get the data I do:
this.$accessor.jacketModule.jackets
but I am getting
TypeError: Cannot read property 'jackets' of undefined
This is how you might do it for SSR support:
const state = {
_currentJacket: { size: 10 },
}
const getters = {
currentJacket(state) => {
return {
...state._currentJacket,
getSize() {
return `size is: ${this.size}`
}
}
}
}
If you are using dispatch
you should call with the namespace: this.$store.dispatch('jacket/loadJackets')
.
And instead of jacketModule
or customerModule
you should use the actual namespace of the module, which is jacket
or customer
. Docs here have this important line:
The key (submodule) needs to match the Nuxt namespace (e.g. ~/store/submodule.ts)
@danielroe thank you so much, I will think about it =)
I will read more about SSR so I don't struggle a lot handling projects with it haha
Thanks again, I really appreciate your attention.