How do I access my state object in store from module? - vuex

I need a data from my store object above in my module, but I cannot access it.
I have a store object
This store object has one or more modules it uses.
I was try it :index.js
import { createStore } from "vuex";
import moduleLayout from "./modules/moduleLayout.js"
export default createStore({
state:{
testData:'Hello World!'
},
modules: { moduleLayout }
})
and have a moduleLayout.js
export default {
state:{
size:100
},
getters:{
getSizeAndText:(state)=>{
return {size:state.size,text:this.state.testData};
//error here, because (this)undefined
//how can i access on here testData
}
}
}
I cannot access testData data from my moduleLayout.js

No need to import index.js.
We can access it by expanding the parameter field.
on "index.js"
import moduleTest from "./modules/moduleTest";
export default{
state:{
size:100
},
modules:{
moduleTest:moduleTest
}
}
on "moduleTest.js"
export default{
state:{
testSize:20
},
getters: {
getSumSize(thisState, getters, state) {
return thisState.testSize+state.size;//this result 120
},
getSumSizeWithParam:(thisState, getters, state) =>(index)=>{
return (thisState.testSize+state.size)*index;//this result 120*index
}
}
}
You definitely don't need to import index.js.

You are not adding the module to the store.
import { createStore } from "vuex";
import moduleLayout from "./modules/moduleLayout.js";
export default createStore({
state: {
testData: 'Hello World!'
},
modules: {
layout: moduleLayout
}
})
Import the store inside module to access the state thats not namespaced by module:
import store from '../index.js'; // whatever the path of where you create and export store
const state = {
size: 100
}
const getters = {
getSizeAndText(state) {
return {
size: state.size,
text: store.state.testData
}
}
}
export default {
state,
getters
}

Related

Vue3 Pinia Store cannot access 'store" before initializsation

I have a UserStore which contains some information about the current user. This store also is responsible for loggin in and out.
In order to make the getters available I map the getters to my computed attribute within my Vue component.
Unfortunately I get an error saying that it cannot access useUserStore before initilization.
This is my component:
<template>
//...
</template>
<script>
import {mapState} from "pinia"
import {useUserStore} from "../../stores/UserStore.js";
import LoginForm from "../../components/forms/LoginForm.vue";
export default {
name: "Login",
components: {LoginForm},
computed: {
...mapState(useUserStore, ["user", "isAuthenticated"]) //commenting this out makes it work
}
}
</script>
This is my store:
import { defineStore } from 'pinia'
import {gameApi} from "../plugins/gameApi.js"
import {router} from "../router.js";
export const useUserStore = defineStore("UserStore", {
persist: true,
state: () => ({
authenticated: false,
_user: null
}),
getters: {
user: (state) => state._user,
isAuthenticated: (state) => state.authenticated
},
actions: {
async checkLoginState() {
// ...
},
async loginUser(fields) {
// ...
},
async logutUser() {
// ...
}
}
})
And my main.js
import {createApp} from 'vue'
import App from './App.vue'
import gameApi from './plugins/gameApi'
import {router} from './router.js'
import store from "./stores/index.js";
createApp(App)
.use(store)
.use(router)
.use(gameApi)
.mount('#app')
And finally my store configuration:
import {createPinia} from "pinia"
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'
import {useUserStore} from "./UserStore.js";
const piniaStore = createPinia()
piniaStore.use(piniaPluginPersistedstate)
export default {
install: (app, options) => {
app.use(piniaStore)
const userStore = useUserStore()
const gameStore = useGameStore()
}
}
I wasn't able to initialize the store using the "old" way comparable with Vuex. Instead I had to make use of the setup() function Pinia Docu:
<script>
import {useUserStore} from "../../stores/UserStore.js";
export default {
name: "RegisterForm",
setup() {
// initialize the store
const userStore = useUserStore()
return {userStore}
},
data() {
return {
// ...
}
},
methods: {
checkLoginState() {
this.userStore.checkLoginState()
}
}
}
</script>

Compile error when trying to access a getter function in Veux 4 store of Quasar V2 beta app

Compile error when trying to access a getter function in Veux 4 store of Quasar V2 beta app.
Unsafe member access ['item/getRandomNumber'] on an any value.eslint#typescript-eslint/no-unsafe-member-access
Error not going even after disabling it.
Please explain the cause the error and how to sort it out.
setup() {
return { randomNumber: computed(() => store.getters['item/getRandomNumber']) }
},
getter.ts under module item
import { GetterTree } from 'vuex';
import { StateInterface } from '../index';
import { ItemStateInterface } from './state';
const getters: GetterTree<ItemStateInterface, StateInterface> = {
getRandomNumber ( /* context */) {
return 20;
}
};
export default getters;
index.ts under module item
import { Module } from 'vuex';
import { StateInterface } from '../index';
import state, { ItemStateInterface } from './state';
import actions from './actions';
import getters from './getters';
import mutations from './mutations';
const itemModule: Module<ItemStateInterface, StateInterface> = {
namespaced: true,
actions,
getters,
mutations,
state
};
export default itemModule;
store/index.ts
import { store } from 'quasar/wrappers'
import { InjectionKey } from 'vue'
import {
createStore,
Store as VuexStore,
useStore as vuexUseStore,
} from 'vuex'
import item from './module-item'
import { ItemStateInterface } from './module-item/state';
export interface StateInterface {
item : ItemStateInterface
}
declare module '#vue/runtime-core' {
interface ComponentCustomProperties {
$store: VuexStore<StateInterface>
}
}
export const storeKey: InjectionKey<VuexStore<StateInterface>> = Symbol('vuex-key')
export default store(function (/* { ssrContext } */) {
const Store = createStore<StateInterface>({
modules: {
item
},
// enable strict mode (adds overhead!)
// for dev mode and --debug builds only
strict: !!process.env.DEBUGGING
})
return Store;
})
export function useStore() {
return vuexUseStore(storeKey)
}

Unable to use Vuex Store in Nuxt layouts

I am trying to use Vuex Store in my layout but can't figure out how to make it work.
Here is what I am doing:
store/sources.ts
import { VuexModule, Module, Mutation, Action } from 'vuex-module-decorators'
import { store } from '#/store'
import axios from 'axios'
const { sourcesEndpoint } = process.env
interface Source {
id: String
}
#Module({
name: 'sources',
namespaced: true,
stateFactory: true,
dynamic: true,
store,
})
export default class Sources extends VuexModule {
private _sources: Source[] = []
get sources(): Source[] {
return this._sources
}
#Mutation
updateSources(sources: Source[]) {
this._sources = sources
}
#Action({ commit: 'updateSources' })
async fetchSources() {
// eslint-disable-next-line no-console
console.log(`!!! ${sourcesEndpoint} !!!`)
return sourcesEndpoint ? await axios.get(sourcesEndpoint) : []
}
}
store/index.ts
import { Store } from 'vuex'
export const store = new Store({})
layouts/default.vue
<script>
import { getModule } from 'vuex-module-decorators'
import Sources from '#/store/sources'
export default {
fetch() {
const sourcesModule = getModule(Sources, this.$store)
sourcesModule.fetchSources()
},
fetchOnServer: false,
}
</script>
And the error I get:
[vuex] must call Vue.use(Vuex) before creating a store instance.
You need to add Vue.use(Vuex), also, you are not including your module in the main store
import { Store } from 'vuex'
import { Sources } from './sources'
Vue.use(Vuex)
export const store = new Store({
modules: {
Sources
}
})

mapActions not returning action from module

I am trying to add the Actions I created in my Vuex module to the Methods of my component.
My component "HomePage.vue" looks like this
import { PlusIcon } from "vue-feather-icons";
import TaskItem from "../TaskItem";
import moment from "moment";
import { mapGetters, mapActions } from "vuex";
export default {
name: "home-page",
components: {
PlusIcon,
TaskItem,
},
methods: {
...mapActions(['fetchTasks'])
},
computed: mapGetters(['allTasks']),
created() {
setInterval(() => {
document.getElementById("time").innerHTML = moment().format("h:mm:ss a");
}, 1000);
},
};
My Vuex module "tasks.js" looks like this
import fs from 'fs'
const state = {
tasks: []
}
const getters = {
allTasks: (state) => state.tasks
}
const actions = {
fetchTasks({commit}) {
let rawdata = fs.readFileSync('../backend/tasks.json')
console.log(JSON.parse(rawdata))
commit('setTasks', JSON.parse(rawdata))
}
}
const mutations = {
setTasks: (state, passedTasks) => (state.tasks.push(passedTasks))
}
export default {
state,
getters,
actions,
mutations,
}
When attempting to use this.fetchTasks() in created(), nothing happens.
When console logging this.fetchTasks() it returns as undefined
Considering your tasks is a module of your vuex store, you should call your mapActions, mapGetters this way :
methods: {
...mapActions('tasks', ['fetchTasks'])
},
computed: {
...mapGetters('tasks', ['allTasks'])
},

Vuex mapstate object undefined and "[vuex] unknown mutation type: "

I'm new with vue.js and vuex and I've an issue with the mapstate object, first I've only one module in my store:
-Store
-index.js
-mutations.js
-actions.js
-state.js
state.js :
export default {
userInfo: {
messages: [{ 1: 'test', 2: 'test' }],
notifications: [],
tasks: []
}
}
So when I try to access the userInfo object everything works correctly:
computed: {
...mapState(["userInfo"]),
}
Then I decided to create modules:
-Store
-modules
-ldap.js
-commons.js
-index.js
So the userInfo is in the commons.js file and now when I try to get the object I always get undefined:
commons.js
// state
const state = {
userInfo: {
messages: [{ 1: 'test', 2: 'test' }],
notifications: [],
tasks: []
}
}
export default {
actions,
mutations,
state
}
Component.vue
computed: {
...mapState(["userInfo"]), // <---- undefined
}
main.js :
import Vue from 'vue'
import Vuex from 'vuex'
import commons from './commons'
import ldap from './modules/ldap'
Vue.use(Vuex)
export default new Vuex.Store({
modules : {
commons,
ldap
}
})
Can you tell me how to access the userInfo object?
Thanks.
Considering:
Your commons.js is as follows:
// state
const state = {
userInfo: {
messages: [{ 1: 'test', 2: 'test' }],
notifications: [],
tasks: []
}
}
export default {
namespaced: true, // <== make sure this is defined
actions,
mutations,
state
}
And main.js imports it like:
import commons from './commons'
// ..
export default new Vuex.Store({
modules : {
commons,
ldap
}
})
Then update on Component.vue:
import { mapState } from 'vuex'
// ...
computed: {
...mapState('commons', ["userInfo"]), // <== add module name here
}
Or
import { createNamespacedHelpers } from 'vuex'
const { mapState, mapActions } = createNamespacedHelpers('commons')
// ... notice module name above ^^^^^^^^^
computed: {
...mapState(["userInfo"]),
}
"[vuex] unknown mutation type: "
Since you are now namespacing your commons module, that modules' mutations now must be prefixed.
So, say you had a mutation like:
const mutations = {
changeName(state, data) {
state.name = data;
}
}
export default {
namespaced: true,
actions,
mutations,
state
}
And you used it like:
this.$store.commit('changeName', "New Name");
Now use it like:
this.$store.commit('commons/changeName', "New Name");
I guess you have namspaced your modules by adding namespaced: true in your module.
So you should pass the module name as the first argument to the mapState helpers so that all bindings are done using that module as the context. See Binding Helpers with Namespace
computed: {
...mapState('commons' , ["userInfo"])
}
You have to define each module as a individual store, here some pseudo example.
// authStore.js
import mutations from './authMutations'
import actions from './authActions'
import getters from './authGetters'
const initialState = {
...
}
export default {
state: initialState,
mutations,
actions,
getters
}
Then, register the modules
import authStore from './authStore'
const store = new Vuex.Store({
modules: {
{...authStore, namespaced: true},
{...postStore, namespaced: true} // some other module defined like auth
}
})
new Vue({
....
store: store
})
And then, on the component use it:
import { createNamespacedHelpers } from 'vuex'
// map state and actions of the module
const { mapState, mapActions } = createNamespacedHelpers('auth')
export default {
computed: {
...mapState({
prop1: 'prop1'
})
}
}
Vuex modules docs
It is really unclear in the documentation but namespaced: true is required to use the map functions.
At least as of the last comment in this discussion
https://github.com/vuejs/vuex/issues/855
Without the need to namespace your modules you can use the callback variant of mapstate:
computed: {
...mapState({
userInfo: state => state.commons.userInfo,
}),
},