I've got a simple VueJS application which uses a Vuex store:
const store = new Vuex.Store({
state: {
organisatie: {}
},
mutations: {
loadOrganisatie (state, payload) {
state.organisatie = payload.organisatie;
console.log(payload.organisatie);
}
}
});
From one of my components I then load the organisation's data to the store as some other components on the page also need its data:
...
created() {
axios.get('/get/'+this.$route.params.orgId)
.then(response => {
this.$store.commit({
type: 'loadOrganisatie',
organisatie: response.data
})
}
...
But the commited state of my Vuex store remains an empty object:
The payload.mutation.organisatie in the devtools is filled with the proper data. But the state.organisatie stays an empty object.
Hope, it will work great for you
mutations: {
loadOrganisatie (state, payload) {
state.organisatie = Object.assign({},payload.organisatie);
console.log(payload.organisatie);
}
}
Related
When a user updates their username in the EditAccount component, the username is updated in the EditAccount component and in vuex store but not in the Navigation component even though stage change is updated to the new user name.
The problem is that the user is seing thier old user name in Navigation component and a updated user name in the EditAccount component and they don't match.
How can I Re render the Navigation component with the new user name?
Below is the the code for user the data in the Navigation component.
Store vuex: index.js
const store = createStore({
// strict: true,
state: {
user: null,
authIsReady: false,
//
// current category
playlistCategory: null,
},
//
getters: {
getUser(state) {
return state.user;
},
},
mutations: {
//
// update playlist category
updatePlaylistCategory(state, payload) {
state.playlistCategory = payload;
},
//
//
setUser(state, payload) {
state.user = payload;
},
//
setAuthIsReady(state, payload) {
state.authIsReady = payload;
},
//
},
actions: {
async editUser(context, payload) {
const { displayNewName, displayNewEmail } = payload;
await updateUserDetails(displayNewName, displayNewEmail);
// get current user
const responseUser = await user;
// set user state
context.commit('setUser', responseUser);
},
},
NavBar.vue
// vue3 and composition api
setup() {
// store
const store = useStore()
//
const { error, logout, isPending } = useLogout()
const router = useRouter()
//
// getters
const user = computed(() => {
return store.getters.getUser.displayName
})
Try adding set and get property:
const user = computed({
get: store.state.user,
set: (val) => store.state.user = val
});
Try using a getter instead acessing the value directly in the state
Getter for user:
export function getUser(state){
return state.getUser
}
and in the component import the getter like this:
<script>
import {mapGetters} from 'vuex'
export default {
computed: {
...mapGetters('*theStoreName*',['getUser'])
},
watch: {
getUser: function(){
//Should be possible to see when the getUser changes here
console.log(this.getUser)
}
}
}
</script>
Note: You have theStoreName for the store name you're using
Maybe the problem is that the store name is missing, or when you did store.state.user you're acessing the store? If it is it, then you should try to inform the variable you're trying to access, like If it is, like store.state.user.name, with the getter it would be: getUser.name
Can someone please help me? I actually don't understand how to initiate localForage (getItem and setItem) in VueX. I have an array on component side, and need to copy it to indexedDB by VueX.
So I have mounted() and watch on the component and trying to activate them by using actions on VueX. Is this possible?
Here is the code on VueX:
enter image description here
and here component side:
enter image description here
enter image description here
export default new Vuex.Store({
state: {
totalTvCount: 10, // The TV inventory
notes: []
},
getters: {
totalTvCount: state => state.totalTvCount,// Here we will create a getter
notes: state => state.notes
},
mutations: {
incTv(state, amount){
state.totalTvCount += amount
} // Here we will create Jenny
},
actions: {
inc(context, amount) {
context.commit('incTv', amount)
}, // Here we will create Larry
setItems(){
localStorage.setItem("notes")
},
getItems(){
localStorage.getItem("notes").then(data => {
this.state.notes = data
})
}
}
Just add a mutation for setting the notes
setNotes(state, notes) {
state.notes = notes
}
then commit the mutation from your action:
getItems({commit}) {
localStorage.getItem("notes")
.then(data => commit('setNotes', data) )
}
I've cloned my state from Vuex to an array in my component, data(). My problem is when I'm trying to remove the first item in the array from my clone with shift()and also add it back with unshift() I get this error msg:
[vuex] Do not mutate vuex store state outside mutation handlers.
How can I delete something in my cloned state that's not effects the actually state itself?
Saving/cloning
beforeMount () {
this.traningArea = this.stateExercises
},
computed: {
...mapState({
userStore: state => state.userStore,
tsStore: state => state.trainingSchemeStore
}),
stateExercises () {
return this.tsStore.schemeExercises
}
}
Trying to run shift() on click and unshift() if user click again
this.traningArea[0].shift()
this.traningArea[0].unshift(obj)
And it's here I've got this error.
STATE
const state = {
trainings: []
}
const actions = {
getTrainingExercise: ({commit}, ids) => {
var payload = {
'trainings_id': ids
}
return Vue.http.post(getTrainingsById, payload,
{headers: getHeader()})
.then(response => {
if (response.status === 200) {
commit('SET_TERL', response.body.data)
}
})
},
const mutations = {
SET_TERL(state, trainings) {
state.trainings.push(trainings)
}
}
i hope that i don't misunderstand you, so i think that the solution would be like this :
const mutations = {
SET_TERL(state, trainings) {
state.trainings.push(trainings)
},
SHIFT(state, index) {
state.trainings[index].shift()
},
UNSHIFT(state, index,obj) {
state.trainings[index].unshift(obj)
}
}
and when you call the method :
this.tsStore.commit("SHIFT",0);
or
this.tsStore.commit("UNSHIFT",0,obj);
I have a Vue.js store with an array and a mutation that sets it after is is reloaded via an API:
export default new Vuex.Store({
state: {
triggeredTests: [],
mutations: {
setTriggeredTest(state, data) {
state.triggeredTests = _
.chain(data)
.forEach((item) => {
item.dateFormatted = moment(item.date).format('DD MMMM YYYY');
item.explanationTest = testMapping.get(item.test);
})
.orderBy('date')
.groupBy('date')
.value();
},
},
});
Should I use some specific mutation method to assign the array here to make the bound components refresh correctly?
The triggeredTests property is already in the store (via state:) so Vue has added change listeners and state.triggeredTests = newArray triggers a change.
You only need Vue.set(state, 'triggeredTests', newArray) when a property was not known before.
However changes may not be visible inside a Component that only listens to changes to an item in the previous array.
Using mapState() and using the triggeredTests variable you'll make sure changes to the array are reflected in the component.
computed: mapState({
item: state => state.triggeredTests.find( ... )
})
If you are resetting the entire array you can use Vue.Set() and create a copy of the array. Below is a rough version of this:
export default new Vuex.Store({
state: {
triggeredTests: [],
},
mutations: {
MUTATE_ITEMS: (state, items) => {
Vue.set(state, 'items', [items]);
}
},
actions: {
loadTriggeredTests: (context, data) => {
const newTriggeredTests = array1.map(item => {
return {
dateFormatted : moment(item.date).format('DD MMMM YYYY'),
explanationTest : testMapping.get(item.test)
}
});
context.commit("MUTATE_ITEMS", newTriggeredTests);
}
}
});
I am creating an app and I have a component "Message" which uses a store to get data back from a JSON file (this will be eventually a database) and the component is as follows:
export default {
props: ['message'],
mounted: function() {
this.$store.dispatch("FETCHMESSAGE", this.message);
},
computed: {
title: function() {
return this.$store.state.message;
}
}
}
I have the following mutation:
FETCHMESSAGE: function (context, type)
{
var data = json.type; // Get the data depending on the type passed in
// COMMIT THE DATA INTO THE STORE
}
And I use it as the following:
<MessageApp message="welcome"></MessageApp>
This works for the most part and the correct message is displayed. The issue is when I have multiple instances of MessageApp being called on the same page. They both show the same message (of the last message) being called. E.g.
<MessageApp message="welcome"></MessageApp>
<MessageApp message="goodbye"></MessageApp>
They will each show the goodbye message. I know why this is happening but is it possible to have multiple instances of the store so that this does not happen?
Vuex is "a centralized store for all the components in an application," as the docs say.
So imagine that you have a variable (or many) which you can use and change from all your components.
Also when you want to get properties from state, it is recommended to use getters.
I can't understand what you want to do, but if you want, you can have multiple states, getters, mutations and actions and use them as modules in the store (read more). See below example from Vuex docs:
const moduleA = {
state: { title: '' },
mutations: { changeTitle(state, payload) { state.title = payload } },
actions: { changeTitle({commit}, payload) { commit('changeTitle', payload) } },
getters: { getTitle(state) { return state.title } }
}
const moduleB = {
state: { title: '' },
mutations: { changeTitle(state, payload) { state.title = payload } },
actions: { changeTitle({commit}, payload) { commit('changeTitle', payload) } },
getters: { getTitle(state) { return state.title } }
}
const store = new Vuex.Store({
modules: {
a: moduleA,
b: moduleB
}
})
store.state.a // -> `moduleA`'s state
store.state.b // -> `moduleB`'s state