I have a file that I'm using to store a global variable that gets changed by 'login' or 'logout' functions. I want to write a unit test that has the value of 'isLoggedIn' set to true or false, then checks for expected behaviour. I can't figure out what I need to do to be able to use the value, this is my file:
import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);
export default new Vuex.Store({
state: {
loggedIn: false,
},
mutations: {
login(state) {
state.loggedIn = true;
},
logout(state) {
state.loggedIn = false;
state.userID = null;
},
},
actions: {
login({ commit }) {
commit('login');
},
logout({ commit }) {
commit('logout');
},
},
getters: {
isLoggedIn: (state) => state.loggedIn,
},
});
And this is the test I'm trying to create:
import { expect } from 'chai';
import { shallowMount } from '#vue/test-utils';
import Home from '#/views/images.vue';
describe('Images.vue', () => {
it('shows that you are logged in', () => {
const welcome_text = 'You are logged in.';
this.$store.dispatch('login');
const wrapper = shallowMount(Home, {});
expect(wrapper.text()).to.include(welcome_text);
});
});
Your getter method isn't returning anything.
https://vuex.vuejs.org/guide/getters.html#property-style-access
Once you change your getter to:
getters: {
isLoggedIn: (state) => return state.loggedIn,
},
You should be able to retrieve this value using:
this.$store.getters.isLoggedIn
Related
two errors help me build with vuex modules
errors: unknown mutation type: setLoggedIn & unknown local mutation type: setLoggedIn, global type: auth/setLoggedIn
vuex version "vuex": "^4.0.0"
the problem occurs in the setLoggedInState(ctx) function
index.js
import Vuex from 'vuex'
import middleware from "./modules/middleware.js";
import auth from "./modules/auth";
export default new Vuex.Store({
namespaced: true,
modules: {
auth,
middleware
}
})
auth.js
const state = {
isLoggedIn: true,
};
const mutation = {
setLoggedIn(state, payload, ) {
state.isLoggedIn = payload;
},
};
const actions = {
setLoggedInState(ctx) {
return new Promise((resolve) => {
if (localStorage.getItem('token')) {
ctx.commit('setLoggedIn', true, {root: true});
resolve(true)
} else {
ctx.commit('setLoggedIn', false, {root: true});
resolve(false)
}
});
},
}
const getters = {
loggedIn(state) {
return state.isLoggedIn;
},
export default {
namespaced: true,
state,
mutation,
actions,
getters
}
Dashboard
import {mapActions} from 'vuex'
export default {
name: "Dashboard",
data: () => ({}),
created() {
this.checkUserState();
},
methods: {
...mapActions({
checkUserState: 'auth/setLoggedInState',
}),
I don’t understand how to fix errors I tried many ways I hope for your help
When you learn something new, please check for missing '; , .' etc.
And be sure that you write 'const mutations' not 'const mutation', following the documentation saving hours))
So basically I have this component and I am using its created hook to fetch data using vue-resource and VUEX action, storing that data in store and right after that trying to get that data using VUEX getter but I am unable to do so. Any work around or I am doing something wrong. I am new to Vue!
Component:
import { mapActions } from 'vuex';
import { mapGetters } from 'vuex';
export default {
components: {
categoryHeader: CategoryHeader,
categoryFooter: CategoryFooter,
AddCategory
},
data() {
return {
openCatAdd: false,
categories: [],
pagination: []
}
},
methods: {
...mapActions([
'getCategories'
]),
...mapGetters([
'allCategories'
])
},
created() {
this.getCategories(1);
this.categories = this.allCategories();
// console.log(this.categories);
}
};
Store:
import Vue from "vue";
const state = {
categories: [],
};
const mutations = {
setCategories: (state, payload) => {
state.categories = payload;
}
};
const actions = {
getCategories: ({commit}, payload) => {
Vue.http.get('categories?page='+payload)
.then(response => {
return response.json();
})
.then(data => {
commit('setCategories', data.data);
}, error => {
console.log(error);
})
}
}
const getters = {
allCategories: state => {
console.log(state.categories);
return state.categories;
}
};
export default {
state,
mutations,
actions,
getters
};
I am trying to use vuex with Quasar. I have created an authentication module as below.
// src/store/auth/index.js
import { api } from 'boot/axios';
export default {
state: {
user: null,
},
getters: {
isAuthenticated: state => !!state.user,
StateUser: state => state.user,
},
mutations: {
setUser(state, username){
state.user = username
},
LogOut(state){
state.user = null
},
},
actions: {
LOGIN: ({ commit }, payload) => {
return new Promise((resolve, reject) => {
api
.post(`/api/login`, payload)
.then(({ data, status }) => {
if (status === 200) {
commit('setUser', data.refresh_token)
resolve(true);
}
})
.catch(error => {
reject(error);
});
});
},
}
}
I imported it in the store
// src/store/index.js
import { store } from 'quasar/wrappers'
import { createStore } from 'vuex'
import auth from './auth'
export default store(function (/* { ssrContext } */) {
const Store = createStore({
modules: {
auth:auth
},
// enable strict mode (adds overhead!)
// for dev mode and --debug builds only
strict: process.env.DEBUGGING
})
return Store
})
And I imported it into MainLayout to check if the user is logged in.
// src/layouts/MainLayout
<template>
</template>
<script>
import { ref, onMounted } from 'vue'
import packageInfo from '../../package.json'
import { useStore } from 'vuex'
export default {
name: 'MainLayout',
setup () {
const $store = useStore;
const connected = ref(false);
function checkLogin(){
//console.log($store)
return connected.value = $store.auth.isAuthenticated
};
onMounted(()=> {
checkLogin();
});
return {
appName: packageInfo.productName,
link:ref('dashboard'),
drawer: ref(false),
miniState: ref(true),
checkLogin,
}
}
}
</script>
But every time, I get the same error :
$store.auth is undefined
I tried to follow the quasar documentation, but I can't. Can anyone tell me what I am doing wrong please?
Thank you.
Someone helped me to find the solution. My error is to have written const $store = useStore instead of const $store = useStore(). Thanks
i have created two store modules and I did the import into main store.
When I load my drawer view, I am getting the next error.
What am I doing wrong here
error:vuex.esm.js [vuex] unknown mutation type: SET_DRAWER
//Drawer.vue
.........
computed: {
...mapState("navstore", ["barColor", "barImage"]),
drawer: {
get() {
return this.$store.state.navstore.drawer;
},
set(val) {
this.$store.commit("SET_DRAWER", val);
},
},
computedItems() {
return null;
//this.items.map(this.mapItem);
},
profile() {
return {
avatar: true,
title: "Gestan",
};
},
},
methods: {},
.........
.........
//store/index.js
import Vue from "vue";
import Vuex from "vuex";
import { default as auth } from ".auth";
import { default as navstore } from "./navStore";
Vue.use(Vuex);
export default new Vuex.Store({
modules: { auth: auth, navstore: navstore },
});
//navstore.js
import Vue from "vue";
import Vuex from "vuex";
Vue.use(Vuex);
const SET_BAR_IMAGE = "NAVSTORE/SET_BAR_IMAGE";
const SET_DRAWER = "NAVSTORE/SET_DRAWER";
export default {
namespaced: true,
state: {
barColor: "rgba(0, 0, 0, .8), rgba(0, 0, 0, .8)",
barImage:
"https://demos.creative-tim.com/material-dashboard/assets/img/sidebar-1.jpg",
drawer: null,
},
mutations: {
[SET_BAR_IMAGE](state, payload) {
state.barImage = payload;
},
[SET_DRAWER](state, payload) {
state.drawer = payload;
},
},
actions: {
actionSetDrawer({ commit }, payload) {
commit(SET_DRAWER, payload);
},
},
};
//auth.js
import Vue from "vue";
import Vuex from "vuex";
import * as storage from "#/store/storage";
import services from "#/services/api/AuthenticationService";
Vue.use(Vuex);
const SET_USER = "AUTH/SET_USER";
const SET_TOKEN = "AUTH/SET_TOKEN";
export default {
namespaced: true,
state: {
token: null,
user: null,
isUserLoggedIn: false,
},
mutations: {
[SET_TOKEN](state, token) {
state.token = token;
state.isUserLoggedIn = !!token;
},
[SET_USER](state, user) {
state.user = user;
},
},
getters: {
isAuthenticated: (state) => !!state.token,
// authStatus: state => state.status
},
actions: {
actionDoLogin({ dispatch }, payload) {
return services.login(payload).then((res) => {
dispatch("actionSetUser", res.data.user);
dispatch("actionSetToken", res.data.token);
});
},
};
You need to remove prefixes with slash from mutation names because your modules namespaced and you will always access this mutations outside indicating a module name like this moduleName/mutation.
For instance:
const SET_BAR_IMAGE = "NAVSTORE/SET_BAR_IMAGE";
const SET_DRAWER = "NAVSTORE/SET_DRAWER";
// should be
const SET_BAR_IMAGE = "SET_BAR_IMAGE";
const SET_DRAWER = "SET_DRAWER";
Because the SET_DRAWER mutation is inside a navspaces module you should call it indicating a module name:
this.$store.commit("navstore/SET_DRAWER", val);
Don't try to call actions inside actions like this:
actionDoLogin({ dispatch }, payload) {
return services.login(payload).then((res) => {
dispatch("actionSetUser", res.data.user);
dispatch("actionSetToken", res.data.token);
});
},
Use mutations in a desired combination:
actionDoLogin({ dispatch }, payload) {
return services.login(payload).then((res) => {
commit(SET_USER, res.data.user);
commit(SET_TOKEN, res.data.token);
});
},
In my ContactForm component , I have 2 computed mapGetters
computed: {
...mapGetters(["language"]),
...mapGetters("authentication", ["loading"]),
the first one is defined in my stoe/getters.js
export const language = state => {
return state.language;
};
the second one is defined in my store/modules/authentication.js
const authentication = {
namespaced: true,
getters: {
user: state => {
return state.user
},
loading: state => {
return state.loading
}
},
I am trying to mock my Vuex store , easy for the first one "language",
export const storeMock = Object.freeze({
state: {},
actions: {},
getters: {
language: () => { . // <= FINE
return "en";
},
authentication: { . // <= . WRONG
loading: () => {
return false;
}
}
}
})
but how should I mock the second one "loading" from the "authentication" module ??
If you console log the store in the app, namespaced getters have a key of namespace/getterName, so I think this should work
export const storeMock = Object.freeze({
state: {},
actions: {},
namespaced: true,
getters: {
language: () => { // <= FINE
return "en";
},
'authentication/loading' : () => {
return false;
}
}
})