Vue3 Pinia Store cannot access 'store" before initializsation - vue.js

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>

Related

I need change vue resources to axios

I'm creating an application based on this code from github.
I need change vue resources to axios, how i can do that ?
I would like to know how to do this keeping the structure of this code.
I'm using vue 3.
Anyone who can help would be very grateful :)
the full code i'm modifying: here
http:
import Vue from 'vue'
import VueResource from 'vue-resource'
import services from './services'
Vue.use(VueResource)
const http = Vue.http
http.options.root = 'https://localhost.com/api'
Object.keys(services).map(service =>{
services[service] = Vue.resource('', {}, services[service])
})
export { http }
export default services
http services:
import { services as auth } from '#/modules/auth'
export default {
auth
}
Actions:
import services from '#/http'
import * as types from './mutation-types'
export const ActionDoLogin = (context, payload) =>{
return services.auth.login(payload)
}
export const ActionSetUser = ({ commit }, payload) => {
commit(types.SET_USER, payload)
}
export const ActionSeToken = ({ commit }, payload) => {
commit(types.SET_TOKEN, payload)
}
Services:
export default {
login: { method: 'post', url: 'login' }
}
Main:
import { createApp } from 'vue'
import App from './App'
import router from './router'
import store from './store'
import './assets/scss/app.scss'
createApp(App).use(store).use(router).mount('#app')
Login view:
<script>
import {mapActions} from 'vuex'
export default {
data: () =>({
form:{
email:'',
pass:''
}
}),
methods:{
...mapActions('auth', ['ActionDoLogin']),
submit(){
this.ActionDoLogin(this.form).then(res =>{
console.log(res.data)
})
}
}
}
</script>

Vue3 - Persisting state with Page refresh

I have just started using Vue3, and am trying to use vuex to manage state. when using Vue2 I would call the store each time the app loads like this:
// mains.js
import VueRouter from "vue-router";
import Vuex from "vuex";
import router from "./routes";
window.Vue = require('vue').default;
Vue.use(VueRouter);
Vue.use(VueMoment);
Vue.use(Vuex);
const store = new Vuex.Store(storeDefinition);
const app = new Vue({
el: '#app',
router,
store,
components: {
"index": Index
},
async created() {
this.$store.dispatch("loadStoredState");
this.$store.dispatch("loadUser");
},
});
This is my vuex store that defines state, mutations and actions for vuex:
// store.js
import { isLoggedIn, logOut } from "./shared/utils/auth";
export default {
state: {
isLoggedIn: false,
user: {}
},
mutations: {
setUser(state, payload) {
state.user = payload;
},
setLoggedIn(state, payload) {
state.isLoggedIn = payload;
}
},
actions: {
loadStoredState(context) {
context.commit("setLoggedIn", isLoggedIn());
},
async loadUser({ commit, dispatch }) {
if (isLoggedIn()) {
try {
const user = (await axios.get("/user")).data;
commit("setUser", user);
commit("setLoggedIn", true);
} catch (error) {
dispatch("logout");
}
}
},
logout({ commit }) {
commit("setUser", {});
commit("setLoggedIn", false);
logOut();
}
},
getters: {}
}
This file manages a cookie for local storage that stores a boolean value for isLoggedIn:
// auth.js
export function isLoggedIn() {
return localStorage.getItem("isLoggedIn") == 'true';
}
export function logIn() {
localStorage.setItem("isLoggedIn", true);
}
export function logOut() {
localStorage.setItem("isLoggedIn", false);
}
But in Vue3 I am creating the main.js file like this:
// mains.js
const { createApp } = require('vue')
import Index from './Index.vue'
import createRouter from './router'
import { createStore } from 'vuex'
import storeDefinition from "./store";
const store = createStore(storeDefinition)
createApp(Index)
.use(createRouter())
.use(store)
.mount('#app')
How can I add the two calls to manage the store to the createApp function?
You can add the created hook to the root component by using the extends option with the component definition:
// main.js
import { createApp } from 'vue'
import Index from './Index.vue'
import createRouter from './router'
import { createStore } from 'vuex'
import storeDefinition from './store'
const store = createStore(storeDefinition)
createApp({
extends: Index,
created() {
this.$store.dispatch('loadStoredState')
this.$store.dispatch('loadUser')
},
})
.use(createRouter())
.use(store)
.mount('#app')
demo

Using vuex PersistedState with vuex modules

I want to use PersistedState https://github.com/robinvdvleuten/vuex-persistedstate with vuex but i can't get to setup correctly.
I have this module inside the store directory
export const auth = {
namespaced: true,
state: {
},
getters: {
countLinks: state => {
return state.links.length
}
},
mutations: {
SET_LINKS: (state, links) => {
state.links = links;
},
//Synchronous
ADD_LINK: (state, link) => {
state.links.push(link)
},
REMOVE_LINK: (state, link) => {
state.links.splice(link, 1)
},
REMOVE_ALL: (state) => {
state.links = []
}
},
actions: {
//Asynchronous
removeLink: (context, link) => {
context.commit("REMOVE_LINK", link)
},
removeAll ({commit}) {
return new Promise((resolve) => {
setTimeout(() => {
commit('REMOVE_ALL')
resolve()
}, 1500)
})
}
}
}
I have named this àuth.js
This is my index.js file also inside store directory
import { createStore } from 'vuex'
import createPersistedState from "vuex-persistedstate"
import { auth } from './auth'
const dataState = createPersistedState({
paths: ['data']
})
const store = createStore({
modules: {
auth
},
plugins: [dataState]
})
I have a total of 7 modules i would like to load and use in various places in my application. To kick things off i just want to load auth module and use it in my home.vue page
This is the script section of my home.vue
import Footer from '#/components/Footer.vue'
import Header from '#/components/Header.vue'
import { mapGetters} from 'vuex'
import store from '../store';
export default {
name: 'Home',
components: {
Footer,Header
},
mounted () {
var links = ['http://google.com','http://coursetro.com','http://youtube.com'];
store.commit('SET_LINKS', links);
},
computed: {
...mapGetters([
'countLinks'
]),
}
}
This is my main.js file
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import i18n from './i18n'
import FlagIcon from 'vue-flag-icon'
import {store} from './store';
createApp(App).use(i18n).use(FlagIcon).use(store).use(router).mount('#app')
When i npm run serve, i get the error
10:7 error 'store' is assigned a value but never used
no-unused-vars
How should i correct this to be able to use auth.js module anywhere in my application?

IONIC + Vue.js not working getters in VUEX

Hello developers I'm working with Ionic and Vue+Vuex in this app, but eventually, I can't access my state from my getters for some reason.
As usually the management state is settled for that purpose with actions getters, mutations, and state.
import { createStore } from "vuex";
const urlLogin = "http://localhost:3006/auth";
const urlUser = "http://localhost:3006/user";
const store = createStore({
state() {
return {
userRegisteredState: false,
allUsersState: [],
};
},
mutations: {
commit_get_all_users(state, payload) {
console.log(payload);
return (state.allUsersState = payload);
},
},
getters: {
getterGetAllUsers(state) {
console.log(state);//checking all state (See image )
console.log(state.allUsersState)//checking only the item I want to consume from state (See image )
return state.allUsersState;
},
},
actions: {
//=================================================================
//============================================================
async getAllUsers({ commit }) {
fetch(`${urlUser}/get/all/users`, {
method: "GET",
headers: {
"Content-Type": "application/json",
"Access-Control-Allow-Origin": "http://localhost:8100",
},
})
.then((result) => {
return result.json();
})
.then((result) => {
console.log(result);
commit("commit_get_all_users", result);
})
.catch((error) => {
console.log(error);
error;
});
},
},
});
export default store;
then on my component , in this case that one referring to get all users I set this logic:
<template>
...some tags...
</template>
<script>
import { mapActions, mapGetters } from "vuex";
export default {
name: "AllUsersComponent",
data() {
return {
allUsers: [],
};
},
methods: {
...mapActions(["getAllUsers"]),
getAllUsersFront() {
this.$store.dispatch("getAllUsers");
},
...some methods....
},
computed: {
...mapGetters(["getterGetAllUsers"]),
getterGetAllUsersFunction() {
console.log(this.$store.getters.getterGetAllUsers);
return this.$store.getters.getterGetAllUsers;
},
},
async mounted() {
this.getAllUsersFront();
},
created() {
this.getAllUsersFront();
this.getterGetAllUsersFunction;
console.log(this.getterGetAllUsersFunction);
},
watch: {},
};
</script>
<style>
</style>
On my main.js file store is imported according to IONC in this way
import { createApp } from "vue";
import './gapi.js'
import App from "./App.vue";
import router from "./router";
import store from "./store/index"; //importando vuex
import loginComponentTag from "./components/Login";
import allUsersComponentTag from "./components/all-users-component"
// import GoogleSignInButton from 'vue-google-signin-button-directive'
import { IonicVue } from "#ionic/vue";
/* Core CSS required for Ionic components to work properly */
import "#ionic/vue/css/core.css";
/* Basic CSS for apps built with Ionic */
import "#ionic/vue/css/normalize.css";
import "#ionic/vue/css/structure.css";
import "#ionic/vue/css/typography.css";
/* Optional CSS utils that can be commented out */
import "#ionic/vue/css/padding.css";
import "#ionic/vue/css/float-elements.css";
import "#ionic/vue/css/text-alignment.css";
import "#ionic/vue/css/text-transformation.css";
import "#ionic/vue/css/flex-utils.css";
import "#ionic/vue/css/display.css";
/* Theme variables */
import "./theme/variables.css";
const app = createApp(App)
.use(IonicVue)
.use(store)
.use(router)
app.component("LoginComponent", loginComponentTag);
app.component("AllUsersComponent",allUsersComponentTag)
router.isReady().then(() => {
app.mount("#app");
});
And my vue.config.js is settled in this way:
module.exports = {
devServer: {
proxy: "http://localhost:8100",
},
};
I checked my logs and eventually.
Literally, the situation is that despite having my state populated with data, unless I retrieve the whole state, I can't retrieve a particular item from it, cause the response is nothing.
Is there any configuration I'm omitting in this process I need to have in mind?

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
}
})