VUEJS + VUEX State reset everytime dispatch action - vue.js

Everytime i dispatch action in vuex it remove my old state of users and add dispatch actions to playlist. I don't know what is problem so sharing screenshot you may understand in image what i am trying to say.
Thing is when application start it works fine with default values but when i add dispatch with some button or event then it remove user state object from vuex but keep playlist with new item in it. I know when dispatch playlist refresh vuex object but how to keep user object same time ?
This is action i added and works fine but i have to do this every time i add something or if other actions then i have to apply same thing.
Any idea i don't have to put user dispatch every time ?
addSongToList() {
playlist.dispatch('addSong', { title: "Beside Me",
mp3: "http://dl.jatt.link/lq.jatt.link/cdn8/1a40cff114c5ee39b75dd3813c3f29dd/cdlzv/Ni%20Mainu-(Mr-Jatt.com).mp3",
});
store.dispatch('updateUser', this.getUser );
}
Thanks
This is my playlist.js store file :
import Vuex from 'vuex'
let state = {
playerList: []
};
let getters = {
getPlaylist: state => {
return state.playerList
}
};
let actions = {
addSong: ({commit}, song) => {
commit('ADD_SONG_TO_PLAYLIST', song)
}
};
let mutations = {
ADD_SONG_TO_PLAYLIST(state, song) {
state.playerList.push(song)
}
};
let playlist = new Vuex.Store({
state,
getters,
mutations,
actions,
});
global.playlist = playlist;
export default playlist
This is user.js
import Vuex from 'vuex'
import playlist from './playlist'
let state = {
user: {}
};
let getters = {
getUser: state => {
return state.user
}
};
let actions = {
updateUser: ({commit}, user) => {
commit('ADD_USER', user)
},
deleteUser: ({commit}) => {
commit('DELETE_USER')
}
};
let mutations = {
ADD_USER(state, user) {
state.user = user
},
DELETE_USER(state) {
state.user = null
}
};
export default new Vuex.Store({
state,
getters,
actions,
modules: {
playlist
},
mutations,
})

Related

Navigation component not getting re rendered with stage change in Vue3

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

How to update API path dynamically in VUEX state

I am trying to dynamically update the API path in my Vuex state. Vuex must have a default path "example.com/api/datasetA.json" set when the page loaded and I want to update the path to "example.com/api/datasetB.json" by the user interaction and fetch the new API data immediately.
The relevant part of my code is as follows (updated code):
VUEX:
export const state = () => ({
apiData: [],
apiId: 'datasetA.json'
});
export const mutations = {
fillApiData: (state, data) => {state.apiData = data},
updateApi: (state, newApiId) => {state.apiId = newApiId;}
};
export const actions = {
async getApiData({commit, state}) {
const response = await this.$axios.$get('https://example/api/'+state.apiId);
commit('fillApiData', response);
then VUE method as follows:
methods: {
updateApi(apiId) {
this.$store.commit('updateApi', apiId)
}
Create a mutation that changes the vuex state. Then run this mutation(commit) in the getApiData function
export const state = () => ({
apiData: [],
apiId: 'datasetA.json'
});
export const mutations = {
updateAPI(state, newApiId ) {
state.apiId = newApiId;
}
};
export const actions = {
async getApiData({commit, state}) {
const response = await this.$axios.$get('https://example/api/'+state.apiId);
commit('updateValue', response);
commit('updateAPI', 'some.new.datasetB.json');
}
}
I can update the state directly by using this.$store.state.apiId = apiId in methods but I know this is bad practice
You are correct. However, if you would like that approach to update the state outside Vuex, you can use mutations to change the Vuex - This is good practice.
Then you can do
this.$store.commit('updateAPI', 'my new value')

Error "[vuex] unknown action type:" with vuejs

Created a new service .js called room.module.js
and inside my Vue view I have the following event on form submit:
submit: function(e) {
e.preventDefault();
var name = this.$refs.name.value;
var capacity = this.$refs.places.value;
// dummy delay
setTimeout(() => {
// send update request
this.$store.dispatch(CREATE_ROOM, {
"name": name,
"places": capacity
});
}, 2000);
and my service room.module.js:
// action types
import ApiService from "#/core/services/api.service";
import JwtService from "#/core/services/jwt.service";
export const CREATE_ROOM = "createNewRoom";
// mutation types
export const SET_ROOM_INFO = "setRoomInfo";
const state = {
room_info: {
name: "Room 1",
places: 10,
status: 1
}
};
const getters = {
currentRoomInfo(state) {
return state.room_info;
}
};
const actions = {
[CREATE_ROOM](context, payload) {
if (JwtService.getToken()) {
ApiService.setHeader();
ApiService.put("/room/create", payload).then(({ data }) => {
context.commit(SET_ROOM_INFO, payload);
return data;
});
}
}
};
const mutations = {
[SET_ROOM_INFO](state, room_info) {
state.room_info = room_info;
}
};
export default {
state,
actions,
mutations,
getters
};
but when I submit the form, the following error occurs:
[vuex] unknown action type: createNewRoom
I know I'm missing something, but can't figure out what.
Any ideas? Thank you!
It seems it needs to be added to the Vuex store.

How to keep items in cart even after refresh using vuex

The problems i am facing are -
My state become empty when I refresh the page
same occurs when i logout and then login
I am new to vuex and I want to build a functioning cart for my e-commerce site.
My cart store is as follows (ps. I have only made a very simple outline to check if it is working as desired):
let dayCare = window.localStorage.getItem('dayCare');
const state = {
dayCare: dayCare ? JSON.parse(dayCare) : [],
};
const getters = {
dayCareItems (state){
return state.dayCare
}
};
const actions = {
dayCareCart({commit}, dayCare){
let data = dayCare
commit('pushDaycareToCart', data)
return data
commit('saveCart')
},
};
const mutations = {
pushDaycareToCart(state, data){
return state.dayCare.push(data)
},
saveCart(state) {
window.localStorage.setItem('dayCare', JSON.stringify(state.dayCare));
}
};
export default {
state,
actions,
mutations,
getters
};
the data for my cart comes from :
<button type="submit" #click="dayCareCart(cartData)">Add To Cart</button>
<script>
import {mapGetters, mapActions} from 'vuex'
export default {
methods: {
...mapActions(["dayCareCart"]),
}
}
</script>
I want to know what i should add to retain the data for the logged in user
Why do you expect it to persist data? You aren't using any kind of database to store the data.
Use the vuex plugin vuex-persist. You can use it to persist data to localstorage or cookies while using everything awesome bout vuex
I figured out how to persist the cart. The save mutation should be called in the push to cart mutation
let dayCare = window.localStorage.getItem('dayCare');
const state = {
dayCare: dayCare ? JSON.parse(dayCare) :[],
};
const getters = {
dayCareItems (state){
return state.dayCare
}
};
const actions = {
dayCareCart({commit}, dayCare){
commit('pushDaycareToCart', dayCare)
},
};
const mutations = {
pushDaycareToCart(state, dayCare){
state.dayCare.push(dayCare)
this.commit('saveCart')
},
saveCart(state) {
window.localStorage.setItem('dayCare', JSON.stringify(state.dayCare));
},
};
export default {
state,
actions,
mutations,
getters
};

Vuex state module structure

I adopted the file structure on vuex with modules. Originally I just had everything in one store file (I don't know what I was thinking). Now that I refactored the code to a better more maintainable structure I am having issues with how to mimic the state that I had before.
My previous state for the user field was just a user object like this:
user: {...}
Now that I used this format
const state = {
}
const mutations = {
fetchUser(state,user){
console.log(user)
state = user;
}
};
const actions = {
currentUser: ({commit}) => {
axios.get('/user').then(response => {
if(response.status == 200){
commit('fetchUser', response.data.data);
}
}).catch(response => {
});
}
}
My state translates to :
user:{}
with an empty object. Shouldn't this assign the user into that user state object or am I missing something.
From docs:
Inside a module's mutations and getters, the first argument received will be the module's local state.
So your mutation should access the module object:
const mutations = {
setUser(state, user){
state.user = user; // Assuming you have a user module **
}
};
** Assuming you have a user module this way:
const store = new Vuex.Store({
modules: {
user: moduleUser,
// more modules ...
}
})
Mutations should only modified the state. You should change your logic to fetch user data from an action only and not from your mutation itself, for example:
const actions = {
currentUser: ({commit}) => {
axios.get('/user').then(response => {
if(response.status == 200){
var response = response.data.data;
commit('setUser', response);
}
}).catch(response => {
});
}
}